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 3 // found in the LICENSE file. 4 5 #ifndef CHROME_BROWSER_EXTENSIONS_API_PROCESSES_PROCESSES_API_H__ 6 #define CHROME_BROWSER_EXTENSIONS_API_PROCESSES_PROCESSES_API_H__ 7 8 #include <set> 9 #include <string> 10 11 #include "base/memory/scoped_ptr.h" 12 #include "chrome/browser/extensions/api/profile_keyed_api_factory.h" 13 #include "chrome/browser/extensions/event_router.h" 14 #include "chrome/browser/extensions/extension_function.h" 15 #include "chrome/browser/task_manager/task_manager.h" 16 #include "components/browser_context_keyed_service/browser_context_keyed_service.h" 17 #include "content/public/browser/notification_registrar.h" 18 #include "content/public/browser/render_process_host.h" 19 #include "content/public/browser/render_widget_host.h" 20 21 class Profile; 22 23 namespace base { 24 class ListValue; 25 } 26 27 namespace extensions { 28 29 // Observes the Task Manager and routes the notifications as events to the 30 // extension system. 31 class ProcessesEventRouter : public TaskManagerModelObserver, 32 public content::NotificationObserver { 33 public: 34 explicit ProcessesEventRouter(Profile* profile); 35 virtual ~ProcessesEventRouter(); 36 37 // Called when an extension process wants to listen to process events. 38 void ListenerAdded(); 39 40 // Called when an extension process with a listener exits or removes it. 41 void ListenerRemoved(); 42 43 // Called on the first invocation of extension API function. This will call 44 // out to the Task Manager to start listening for notifications. Returns 45 // true if this was the first call and false if this has already been called. 46 void StartTaskManagerListening(); 47 48 bool is_task_manager_listening() { return task_manager_listening_; } 49 50 private: 51 // content::NotificationObserver implementation. 52 virtual void Observe(int type, 53 const content::NotificationSource& source, 54 const content::NotificationDetails& details) OVERRIDE; 55 56 // TaskManagerModelObserver methods. 57 virtual void OnItemsAdded(int start, int length) OVERRIDE; 58 virtual void OnModelChanged() OVERRIDE {} 59 virtual void OnItemsChanged(int start, int length) OVERRIDE; 60 virtual void OnItemsRemoved(int start, int length) OVERRIDE {} 61 virtual void OnItemsToBeRemoved(int start, int length) OVERRIDE; 62 63 // Internal helpers for processing notifications. 64 void ProcessHangEvent(content::RenderWidgetHost* widget); 65 void ProcessClosedEvent( 66 content::RenderProcessHost* rph, 67 content::RenderProcessHost::RendererClosedDetails* details); 68 69 void DispatchEvent(const char* event_name, 70 scoped_ptr<base::ListValue> event_args); 71 72 // Determines whether there is a registered listener for the specified event. 73 // It helps to avoid collecing data if no one is interested in it. 74 bool HasEventListeners(const std::string& event_name); 75 76 // Used for tracking registrations to process related notifications. 77 content::NotificationRegistrar registrar_; 78 79 Profile* profile_; 80 81 // TaskManager to observe for updates. 82 TaskManagerModel* model_; 83 84 // Count of listeners, so we avoid sending updates if no one is interested. 85 int listeners_; 86 87 // Indicator whether we've initialized the Task Manager listeners. This is 88 // done once for the lifetime of this object. 89 bool task_manager_listening_; 90 91 DISALLOW_COPY_AND_ASSIGN(ProcessesEventRouter); 92 }; 93 94 // The profile-keyed service that manages the processes extension API. 95 class ProcessesAPI : public ProfileKeyedAPI, 96 public EventRouter::Observer { 97 public: 98 explicit ProcessesAPI(Profile* profile); 99 virtual ~ProcessesAPI(); 100 101 // BrowserContextKeyedService implementation. 102 virtual void Shutdown() OVERRIDE; 103 104 // ProfileKeyedAPI implementation. 105 static ProfileKeyedAPIFactory<ProcessesAPI>* GetFactoryInstance(); 106 107 // Convenience method to get the ProcessesAPI for a profile. 108 static ProcessesAPI* Get(Profile* profile); 109 110 ProcessesEventRouter* processes_event_router(); 111 112 // EventRouter::Observer implementation. 113 virtual void OnListenerAdded(const EventListenerInfo& details) OVERRIDE; 114 virtual void OnListenerRemoved(const EventListenerInfo& details) OVERRIDE; 115 116 private: 117 friend class ProfileKeyedAPIFactory<ProcessesAPI>; 118 119 Profile* profile_; 120 121 // ProfileKeyedAPI implementation. 122 static const char* service_name() { 123 return "ProcessesAPI"; 124 } 125 static const bool kServiceRedirectedInIncognito = true; 126 static const bool kServiceIsNULLWhileTesting = true; 127 128 // Created lazily on first access. 129 scoped_ptr<ProcessesEventRouter> processes_event_router_; 130 }; 131 132 // This extension function returns the Process object for the renderer process 133 // currently in use by the specified Tab. 134 class GetProcessIdForTabFunction : public AsyncExtensionFunction, 135 public content::NotificationObserver { 136 public: 137 GetProcessIdForTabFunction(); 138 139 private: 140 virtual ~GetProcessIdForTabFunction() {} 141 virtual bool RunImpl() OVERRIDE; 142 143 // content::NotificationObserver implementation. 144 virtual void Observe(int type, 145 const content::NotificationSource& source, 146 const content::NotificationDetails& details) OVERRIDE; 147 148 void GetProcessIdForTab(); 149 150 content::NotificationRegistrar registrar_; 151 152 // Storage for the tab ID parameter. 153 int tab_id_; 154 155 DECLARE_EXTENSION_FUNCTION("experimental.processes.getProcessIdForTab", 156 EXPERIMENTAL_PROCESSES_GETPROCESSIDFORTAB) 157 }; 158 159 // Extension function that allows terminating Chrome subprocesses, by supplying 160 // the unique ID for the process coming from the ChildProcess ID pool. 161 // Using unique IDs instead of OS process IDs allows two advantages: 162 // * guaranteed uniqueness, since OS process IDs can be reused 163 // * guards against killing non-Chrome processes 164 class TerminateFunction : public AsyncExtensionFunction, 165 public content::NotificationObserver { 166 public: 167 TerminateFunction(); 168 169 private: 170 virtual ~TerminateFunction() {} 171 virtual bool RunImpl() OVERRIDE; 172 173 // content::NotificationObserver implementation. 174 virtual void Observe(int type, 175 const content::NotificationSource& source, 176 const content::NotificationDetails& details) OVERRIDE; 177 178 void TerminateProcess(); 179 180 content::NotificationRegistrar registrar_; 181 182 // Storage for the process ID parameter. 183 int process_id_; 184 185 DECLARE_EXTENSION_FUNCTION("experimental.processes.terminate", 186 EXPERIMENTAL_PROCESSES_TERMINATE) 187 }; 188 189 // Extension function which returns a set of Process objects, containing the 190 // details corresponding to the process IDs supplied as input. 191 class GetProcessInfoFunction : public AsyncExtensionFunction, 192 public content::NotificationObserver { 193 public: 194 GetProcessInfoFunction(); 195 196 private: 197 virtual ~GetProcessInfoFunction(); 198 virtual bool RunImpl() OVERRIDE; 199 200 // content::NotificationObserver implementation. 201 virtual void Observe(int type, 202 const content::NotificationSource& source, 203 const content::NotificationDetails& details) OVERRIDE; 204 205 void GatherProcessInfo(); 206 207 content::NotificationRegistrar registrar_; 208 209 // Member variables to store the function parameters 210 std::vector<int> process_ids_; 211 #if defined(ENABLE_TASK_MANAGER) 212 bool memory_; 213 #endif 214 215 DECLARE_EXTENSION_FUNCTION("experimental.processes.getProcessInfo", 216 EXPERIMENTAL_PROCESSES_GETPROCESSINFO) 217 }; 218 219 } // namespace extensions 220 221 #endif // CHROME_BROWSER_EXTENSIONS_API_PROCESSES_PROCESSES_API_H__ 222