blob: 522354a8e04d905ee41c3a7f1c10ee0b07163db2 [file] [log] [blame]
// 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 <set>
#include <string>
#include "base/memory/scoped_ptr.h"
#include "chrome/browser/extensions/chrome_extension_function.h"
#include "chrome/browser/task_manager/task_manager.h"
#include "components/keyed_service/core/keyed_service.h"
#include "content/public/browser/notification_registrar.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/render_widget_host.h"
#include "extensions/browser/browser_context_keyed_api_factory.h"
#include "extensions/browser/event_router.h"
namespace base {
class ListValue;
}
namespace content {
class BrowserContext;
}
namespace extensions {
// Observes the Task Manager and routes the notifications as events to the
// extension system.
class ProcessesEventRouter : public TaskManagerModelObserver,
public content::NotificationObserver {
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();
// Called on the first invocation of extension API function. This will call
// out to the Task Manager to start listening for notifications. Returns
// true if this was the first call and false if this has already been called.
void StartTaskManagerListening();
bool is_task_manager_listening() { return task_manager_listening_; }
private:
// content::NotificationObserver implementation.
void Observe(int type,
const content::NotificationSource& source,
const content::NotificationDetails& details) override;
// TaskManagerModelObserver methods.
void OnItemsAdded(int start, int length) override;
void OnModelChanged() override {}
void OnItemsChanged(int start, int length) override;
void OnItemsRemoved(int start, int length) override {}
void OnItemsToBeRemoved(int start, int length) override;
// Internal helpers for processing notifications.
void ProcessHangEvent(content::RenderWidgetHost* widget);
void ProcessClosedEvent(
content::RenderProcessHost* rph,
content::RenderProcessHost::RendererClosedDetails* details);
void DispatchEvent(const std::string& event_name,
scoped_ptr<base::ListValue> event_args);
// Determines whether there is a registered listener for the specified event.
// It helps to avoid collecing data if no one is interested in it.
bool HasEventListeners(const std::string& event_name);
// Used for tracking registrations to process related notifications.
content::NotificationRegistrar registrar_;
content::BrowserContext* browser_context_;
// TaskManager to observe for updates.
TaskManagerModel* model_;
// Count of listeners, so we avoid sending updates if no one is interested.
int listeners_;
// Indicator whether we've initialized the Task Manager listeners. This is
// done once for the lifetime of this object.
bool task_manager_listening_;
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;
// KeyedService implementation.
void Shutdown() override;
// BrowserContextKeyedAPI implementation.
static BrowserContextKeyedAPIFactory<ProcessesAPI>* GetFactoryInstance();
// Convenience method to get the ProcessesAPI for a profile.
static ProcessesAPI* Get(content::BrowserContext* context);
ProcessesEventRouter* processes_event_router();
// EventRouter::Observer implementation.
void OnListenerAdded(const EventListenerInfo& details) override;
void OnListenerRemoved(const EventListenerInfo& details) override;
private:
friend class BrowserContextKeyedAPIFactory<ProcessesAPI>;
content::BrowserContext* browser_context_;
// BrowserContextKeyedAPI implementation.
static const char* service_name() {
return "ProcessesAPI";
}
static const bool kServiceRedirectedInIncognito = true;
static const bool kServiceIsNULLWhileTesting = true;
// Created lazily on first access.
scoped_ptr<ProcessesEventRouter> processes_event_router_;
};
// This extension function returns the Process object for the renderer process
// currently in use by the specified Tab.
class GetProcessIdForTabFunction : public ChromeAsyncExtensionFunction {
public:
GetProcessIdForTabFunction();
private:
~GetProcessIdForTabFunction() override {}
bool RunAsync() override;
void GetProcessIdForTab();
// Storage for the tab ID parameter.
int tab_id_;
DECLARE_EXTENSION_FUNCTION("processes.getProcessIdForTab",
PROCESSES_GETPROCESSIDFORTAB)
};
// 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 TerminateFunction : public ChromeAsyncExtensionFunction {
public:
TerminateFunction();
private:
~TerminateFunction() override {}
bool RunAsync() override;
void TerminateProcess();
// Storage for the process ID parameter.
int process_id_;
DECLARE_EXTENSION_FUNCTION("processes.terminate",
PROCESSES_TERMINATE)
};
// Extension function which returns a set of Process objects, containing the
// details corresponding to the process IDs supplied as input.
class GetProcessInfoFunction : public ChromeAsyncExtensionFunction {
public:
GetProcessInfoFunction();
private:
~GetProcessInfoFunction() override;
bool RunAsync() override;
void GatherProcessInfo();
// Member variables to store the function parameters
std::vector<int> process_ids_;
#if defined(ENABLE_TASK_MANAGER)
bool memory_;
#endif
DECLARE_EXTENSION_FUNCTION("processes.getProcessInfo",
PROCESSES_GETPROCESSINFO)
};
} // namespace extensions
#endif // CHROME_BROWSER_EXTENSIONS_API_PROCESSES_PROCESSES_API_H__