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 21namespace base { 22class ListValue; 23} 24 25namespace content { 26class BrowserContext; 27} 28 29namespace extensions { 30 31// Observes the Task Manager and routes the notifications as events to the 32// extension system. 33class 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 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; 60 virtual void OnModelChanged() OVERRIDE {} 61 virtual void OnItemsChanged(int start, int length) OVERRIDE; 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. 97class 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. 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. 136class GetProcessIdForTabFunction : public ChromeAsyncExtensionFunction { 137 public: 138 GetProcessIdForTabFunction(); 139 140 private: 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 158class TerminateFunction : public ChromeAsyncExtensionFunction { 159 public: 160 TerminateFunction(); 161 162 private: 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. 177class 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