Home | History | Annotate | Download | only in processes
      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