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
|
// Copyright 2014 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef EXTENSIONS_BROWSER_EXTENSION_FUNCTION_DISPATCHER_H_
#define EXTENSIONS_BROWSER_EXTENSION_FUNCTION_DISPATCHER_H_
#include <map>
#include <set>
#include <string>
#include <vector>
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/values.h"
#include "extensions/browser/extension_function.h"
#include "extensions/common/features/feature.h"
#include "extensions/common/mojom/context_type.mojom-forward.h"
#include "extensions/common/mojom/frame.mojom.h"
#include "extensions/common/mojom/service_worker_host.mojom.h"
#include "ipc/ipc_sender.h"
namespace content {
class BrowserContext;
class RenderFrameHost;
class RenderProcessHost;
class WebContents;
}
namespace extensions {
class Extension;
class ExtensionAPI;
class WindowController;
// ExtensionFunctionDispatcher receives requests to execute functions from
// Chrome extensions running in a RenderFrameHost and dispatches them to the
// appropriate handler. It lives entirely on the UI thread.
//
// ExtensionFunctionDispatcher should be a member of some class that hosts
// RenderFrameHosts and wants them to be able to display extension content.
// This class should also implement ExtensionFunctionDispatcher::Delegate.
//
// Note that a single ExtensionFunctionDispatcher does *not* correspond to a
// single RVH, a single extension, or a single URL. This is by design so that
// we can gracefully handle cases like WebContents, where the RVH, extension,
// and URL can all change over the lifetime of the tab. Instead, these items
// are all passed into each request.
class ExtensionFunctionDispatcher {
public:
class Delegate {
public:
// Returns the WindowController associated with this delegate, or NULL if no
// window is associated with the delegate.
virtual WindowController* GetExtensionWindowController() const;
// Asks the delegate for any relevant WebContents associated with this
// context. For example, the WebContents in which an infobar or
// chrome-extension://<id> URL are being shown. Callers must check for a
// NULL return value (as in the case of a background page).
virtual content::WebContents* GetAssociatedWebContents() const;
// If the associated web contents is not null, returns that. Otherwise,
// returns the next most relevant visible web contents. Callers must check
// for a NULL return value (as in the case of a background page).
virtual content::WebContents* GetVisibleWebContents() const;
protected:
virtual ~Delegate() {}
};
// Public constructor. Callers must ensure that:
// - This object outlives any RenderFrameHost's passed to created
// ExtensionFunctions.
explicit ExtensionFunctionDispatcher(
content::BrowserContext* browser_context);
~ExtensionFunctionDispatcher();
// Dispatches a request and the response is sent in `callback` that is a reply
// of mojom::LocalFrameHost::Request.
void Dispatch(mojom::RequestParamsPtr params,
content::RenderFrameHost& frame,
mojom::LocalFrameHost::RequestCallback callback);
// Message handlers.
// Dispatches a request for service woker and the response is sent to the
// corresponding render process in an ExtensionMsg_ResponseWorker message.
void DispatchForServiceWorker(
mojom::RequestParamsPtr params,
int render_process_id,
mojom::ServiceWorkerHost::RequestWorkerCallback callback);
// Called when an ExtensionFunction is done executing, after it has sent
// a response (if any) to the extension.
void OnExtensionFunctionCompleted(ExtensionFunction& extension_function);
// See the Delegate class for documentation on these methods.
// TODO(devlin): None of these belong here. We should kill
// ExtensionFunctionDispatcher::Delegate.
WindowController* GetExtensionWindowController() const;
content::WebContents* GetAssociatedWebContents() const;
content::WebContents* GetVisibleWebContents() const;
// The BrowserContext that this dispatcher is associated with.
content::BrowserContext* browser_context() { return browser_context_; }
void set_delegate(Delegate* delegate) { delegate_ = delegate; }
// Adds a function object to the set of objects waiting for
// responses from the renderer.
void AddResponseTarget(ExtensionFunction* func);
// Processes a response ack from a renderer.
void ProcessResponseAck(const base::Uuid& request_uuid);
base::WeakPtr<ExtensionFunctionDispatcher> AsWeakPtr() {
return weak_ptr_factory_.GetWeakPtr();
}
private:
// Helper to create an ExtensionFunction to handle the function given by
// `params`.
// Does not set subclass properties, or include_incognito.
scoped_refptr<ExtensionFunction> CreateExtensionFunction(
const mojom::RequestParams& params_without_args,
base::ListValue arguments,
const Extension* extension,
int requesting_process_id,
bool is_worker_request,
const GURL* render_frame_host_url,
mojom::ContextType context_type,
ExtensionAPI* api,
ExtensionFunction::ResponseCallback callback,
content::RenderFrameHost* render_frame_host);
void DispatchWithCallbackInternal(
mojom::RequestParamsPtr params,
content::RenderFrameHost* render_frame_host,
content::RenderProcessHost& render_process_host,
ExtensionFunction::ResponseCallback callback);
void RemoveWorkerCallbacksForProcess(int render_process_id);
raw_ptr<content::BrowserContext, AcrossTasksDanglingUntriaged>
browser_context_;
raw_ptr<Delegate, AcrossTasksDanglingUntriaged> delegate_;
// The set of ExtensionFunction instances waiting for responses from
// the renderer. These are removed once the response is processed.
// The lifetimes of the instances are managed by the instances themselves.
std::set<raw_ptr<ExtensionFunction, SetExperimental>> response_targets_;
base::WeakPtrFactory<ExtensionFunctionDispatcher> weak_ptr_factory_{this};
};
} // namespace extensions
#endif // EXTENSIONS_BROWSER_EXTENSION_FUNCTION_DISPATCHER_H_
|