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