1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
|
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_EXTENSIONS_API_PROCESSES_PROCESSES_API_H__
#define CHROME_BROWSER_EXTENSIONS_API_PROCESSES_PROCESSES_API_H__
#include <vector>
#include "base/macros.h"
#include "chrome/browser/task_management/task_manager_observer.h"
#include "extensions/browser/browser_context_keyed_api_factory.h"
#include "extensions/browser/event_router.h"
#include "extensions/browser/extension_event_histogram_value.h"
#include "extensions/browser/extension_function.h"
class ProcessesApiTest;
namespace extensions {
// Observes the Task Manager and routes the notifications as events to the
// extension system.
class ProcessesEventRouter : public task_management::TaskManagerObserver {
public:
explicit ProcessesEventRouter(content::BrowserContext* context);
~ProcessesEventRouter() override;
// Called when an extension process wants to listen to process events.
void ListenerAdded();
// Called when an extension process with a listener exits or removes it.
void ListenerRemoved();
// task_management::TaskManagerObserver:
void OnTaskAdded(task_management::TaskId id) override;
void OnTaskToBeRemoved(task_management::TaskId id) override;
void OnTasksRefreshed(const task_management::TaskIdList& task_ids) override {}
void OnTasksRefreshedWithBackgroundCalculations(
const task_management::TaskIdList& task_ids) override;
void OnTaskUnresponsive(task_management::TaskId id) override;
private:
friend class ::ProcessesApiTest;
void DispatchEvent(events::HistogramValue histogram_value,
const std::string& event_name,
scoped_ptr<base::ListValue> event_args) const;
// Determines whether there is a registered listener for the specified event.
// It helps to avoid collecting data if no one is interested in it.
bool HasEventListeners(const std::string& event_name) const;
// Returns true if the task with the given |id| should be reported as created
// or removed. |out_child_process_host_id| will be filled with the valid ID of
// the process to report in the event.
bool ShouldReportOnCreatedOrOnExited(task_management::TaskId id,
int* out_child_process_host_id) const;
// Updates the requested task manager refresh types flags depending on what
// events are being listened to by extensions.
void UpdateRefreshTypesFlagsBasedOnListeners();
content::BrowserContext* browser_context_;
// Count of listeners, so we avoid sending updates if no one is interested.
int listeners_;
DISALLOW_COPY_AND_ASSIGN(ProcessesEventRouter);
};
////////////////////////////////////////////////////////////////////////////////
// The profile-keyed service that manages the processes extension API.
class ProcessesAPI : public BrowserContextKeyedAPI,
public EventRouter::Observer {
public:
explicit ProcessesAPI(content::BrowserContext* context);
~ProcessesAPI() override;
// BrowserContextKeyedAPI:
static BrowserContextKeyedAPIFactory<ProcessesAPI>* GetFactoryInstance();
// Convenience method to get the ProcessesAPI for a profile.
static ProcessesAPI* Get(content::BrowserContext* context);
// KeyedService:
void Shutdown() override;
// EventRouter::Observer:
void OnListenerAdded(const EventListenerInfo& details) override;
void OnListenerRemoved(const EventListenerInfo& details) override;
ProcessesEventRouter* processes_event_router();
private:
friend class BrowserContextKeyedAPIFactory<ProcessesAPI>;
// BrowserContextKeyedAPI:
static const char* service_name() { return "ProcessesAPI"; }
static const bool kServiceRedirectedInIncognito = true;
static const bool kServiceIsNULLWhileTesting = true;
content::BrowserContext* browser_context_;
// Created lazily on first access.
scoped_ptr<ProcessesEventRouter> processes_event_router_;
DISALLOW_COPY_AND_ASSIGN(ProcessesAPI);
};
////////////////////////////////////////////////////////////////////////////////
// This extension function returns the Process object for the renderer process
// currently in use by the specified Tab.
class ProcessesGetProcessIdForTabFunction : public UIThreadExtensionFunction {
public:
// UIThreadExtensionFunction:
ExtensionFunction::ResponseAction Run() override;
DECLARE_EXTENSION_FUNCTION("processes.getProcessIdForTab",
PROCESSES_GETPROCESSIDFORTAB);
private:
~ProcessesGetProcessIdForTabFunction() override {}
};
////////////////////////////////////////////////////////////////////////////////
// Extension function that allows terminating Chrome subprocesses, by supplying
// the unique ID for the process coming from the ChildProcess ID pool.
// Using unique IDs instead of OS process IDs allows two advantages:
// * guaranteed uniqueness, since OS process IDs can be reused.
// * guards against killing non-Chrome processes.
class ProcessesTerminateFunction : public UIThreadExtensionFunction {
public:
// UIThreadExtensionFunction:
ExtensionFunction::ResponseAction Run() override;
DECLARE_EXTENSION_FUNCTION("processes.terminate", PROCESSES_TERMINATE);
private:
~ProcessesTerminateFunction() override {}
// Functions to get the process handle on the IO thread and post it back to
// the UI thread from processing.
base::ProcessHandle GetProcessHandleOnIO(int child_process_host_id) const;
void OnProcessHandleOnUI(base::ProcessHandle handle);
// Terminates the process with |handle| if it's valid and is allowed to be
// terminated. Returns the response value of this extension function to be
// sent.
ExtensionFunction::ResponseValue TerminateIfAllowed(
base::ProcessHandle handle);
// Caches the parameter of this function. To be accessed only on the UI
// thread.
int child_process_host_id_ = 0;
};
////////////////////////////////////////////////////////////////////////////////
// Extension function which returns a set of Process objects, containing the
// details corresponding to the process IDs supplied as input.
class ProcessesGetProcessInfoFunction :
public UIThreadExtensionFunction,
public task_management::TaskManagerObserver {
public:
ProcessesGetProcessInfoFunction();
// UIThreadExtensionFunction:
ExtensionFunction::ResponseAction Run() override;
// task_management::TaskManagerObserver:
void OnTaskAdded(task_management::TaskId id) override {}
void OnTaskToBeRemoved(task_management::TaskId id) override {}
void OnTasksRefreshed(const task_management::TaskIdList& task_ids) override;
void OnTasksRefreshedWithBackgroundCalculations(
const task_management::TaskIdList& task_ids) override;
DECLARE_EXTENSION_FUNCTION("processes.getProcessInfo",
PROCESSES_GETPROCESSINFO);
private:
~ProcessesGetProcessInfoFunction() override;
// Since we don't report optional process data like CPU usage in the results
// of this function, the only background calculations we want to watch is
// memory usage (which will be requested only when |include_memory_| is true).
// This function will be called by either OnTasksRefreshed() or
// OnTasksRefreshedWithBackgroundCalculations() depending on whether memory is
// requested.
void GatherDataAndRespond(const task_management::TaskIdList& task_ids);
std::vector<int> process_host_ids_;
bool include_memory_ = false;
};
} // namespace extensions
#endif // CHROME_BROWSER_EXTENSIONS_API_PROCESSES_PROCESSES_API_H__
|