• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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