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 197 198 199 200 201
|
// Copyright 2012 The Chromium Authors
// 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/memory/raw_ptr.h"
#include "base/values.h"
#include "chrome/browser/task_manager/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_manager::TaskManagerObserver {
public:
explicit ProcessesEventRouter(content::BrowserContext* context);
ProcessesEventRouter(const ProcessesEventRouter&) = delete;
ProcessesEventRouter& operator=(const ProcessesEventRouter&) = delete;
~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_manager::TaskManagerObserver:
void OnTaskAdded(task_manager::TaskId id) override;
void OnTaskToBeRemoved(task_manager::TaskId id) override;
void OnTasksRefreshed(const task_manager::TaskIdList& task_ids) override {}
void OnTasksRefreshedWithBackgroundCalculations(
const task_manager::TaskIdList& task_ids) override;
void OnTaskUnresponsive(task_manager::TaskId id) override;
private:
friend class ::ProcessesApiTest;
void DispatchEvent(events::HistogramValue histogram_value,
const std::string& event_name,
base::Value::List 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_manager::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();
raw_ptr<content::BrowserContext> browser_context_;
// Count of listeners, so we avoid sending updates if no one is interested.
int listeners_;
};
////////////////////////////////////////////////////////////////////////////////
// The profile-keyed service that manages the processes extension API.
class ProcessesAPI : public BrowserContextKeyedAPI,
public EventRouter::Observer {
public:
explicit ProcessesAPI(content::BrowserContext* context);
ProcessesAPI(const ProcessesAPI&) = delete;
ProcessesAPI& operator=(const ProcessesAPI&) = delete;
~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;
raw_ptr<content::BrowserContext> browser_context_;
// Created lazily on first access.
std::unique_ptr<ProcessesEventRouter> processes_event_router_;
};
////////////////////////////////////////////////////////////////////////////////
// This extension function returns the Process object for the renderer process
// currently in use by the specified Tab.
class ProcessesGetProcessIdForTabFunction : public ExtensionFunction {
public:
// ExtensionFunction:
ExtensionFunction::ResponseAction Run() override;
DECLARE_EXTENSION_FUNCTION("processes.getProcessIdForTab",
PROCESSES_GETPROCESSIDFORTAB)
private:
~ProcessesGetProcessIdForTabFunction() override = default;
};
////////////////////////////////////////////////////////////////////////////////
// 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 ExtensionFunction {
public:
// ExtensionFunction:
ExtensionFunction::ResponseAction Run() override;
DECLARE_EXTENSION_FUNCTION("processes.terminate", PROCESSES_TERMINATE)
private:
~ProcessesTerminateFunction() override = default;
// 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 ExtensionFunction,
public task_manager::TaskManagerObserver {
public:
ProcessesGetProcessInfoFunction();
// ExtensionFunction:
ExtensionFunction::ResponseAction Run() override;
// task_manager::TaskManagerObserver:
void OnTaskAdded(task_manager::TaskId id) override {}
void OnTaskToBeRemoved(task_manager::TaskId id) override {}
void OnTasksRefreshed(const task_manager::TaskIdList& task_ids) override;
void OnTasksRefreshedWithBackgroundCalculations(
const task_manager::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_manager::TaskIdList& task_ids);
std::vector<int> process_host_ids_;
bool include_memory_ = false;
};
} // namespace extensions
#endif // CHROME_BROWSER_EXTENSIONS_API_PROCESSES_PROCESSES_API_H__
|