| Index: content/public/browser/web_contents_interface_registry.h
|
| diff --git a/content/public/browser/web_contents_interface_registry.h b/content/public/browser/web_contents_interface_registry.h
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..cc5a99fcc6106912350b104287cc4aaadefd45b4
|
| --- /dev/null
|
| +++ b/content/public/browser/web_contents_interface_registry.h
|
| @@ -0,0 +1,127 @@
|
| +// Copyright 2016 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 CONTENT_PUBLIC_BROWSER_WEB_CONTENTS_INTERFACE_REGISTRY_H_
|
| +#define CONTENT_PUBLIC_BROWSER_WEB_CONTENTS_INTERFACE_REGISTRY_H_
|
| +
|
| +#include <map>
|
| +#include <string>
|
| +
|
| +#include "base/macros.h"
|
| +#include "base/memory/weak_ptr.h"
|
| +#include "content/common/content_export.h"
|
| +#include "mojo/public/cpp/bindings/associated_binding_set.h"
|
| +#include "mojo/public/cpp/bindings/associated_interface_request.h"
|
| +#include "mojo/public/cpp/bindings/scoped_interface_endpoint_handle.h"
|
| +
|
| +namespace content {
|
| +
|
| +class RenderFrameHost;
|
| +class WebContents;
|
| +
|
| +// A helper class to hold per-frame associated interface bindings for every
|
| +// frame belonging to a single WebContents. Each WebContents owns a single
|
| +// instance of this class.
|
| +class CONTENT_EXPORT WebContentsInterfaceRegistry {
|
| + public:
|
| + virtual ~WebContentsInterfaceRegistry() {}
|
| +
|
| + // Returns the RenderFrameHost targeted by the current binding dispatch. See
|
| + // AddFrameInterface() below for details.
|
| + virtual RenderFrameHost* GetCurrentTargetFrame() = 0;
|
| +
|
| + virtual base::WeakPtr<WebContentsInterfaceRegistry> GetWeakPtr() = 0;
|
| +
|
| + // Allows test code to control the target frame currently seen by calls to
|
| + // GetCurrentTargetFrame(). Useful when simulating incoming message calls.
|
| + virtual void SetCurrentTargetFrameForTesting(
|
| + RenderFrameHost* render_frame_host) = 0;
|
| +
|
| + // Adds a new interface to the registry. A separate Interface binding is
|
| + // (lazily) established for every RenderFrameHost belonging to every
|
| + // WebContents the registry knows about.
|
| + //
|
| + // Incoming messages on Interface are routed to |impl|, and during the extent
|
| + // of any message dispatch (i.e. any Interface call on |impl|), |impl| may
|
| + // call GetCurrentTargetFrame() above to get the RenderFrameHost whose
|
| + // specific binding was targeted by the message.
|
| + template <typename Interface>
|
| + void AddFrameInterface(Interface* iface) {
|
| + AddFrameInterface(Interface::Name_,
|
| + base::MakeUnique<FrameInterface<Interface>>(iface, this));
|
| + }
|
| +
|
| + template <typename Interface>
|
| + void RemoveFrameInterface() { RemoveFrameInterface(Interface::Name_); }
|
| +
|
| + protected:
|
| + class FrameInterfaceBase {
|
| + public:
|
| + virtual ~FrameInterfaceBase() {}
|
| +
|
| + virtual void AddBinding(RenderFrameHost* render_frame_host,
|
| + mojo::ScopedInterfaceEndpointHandle handle) = 0;
|
| + virtual void RemoveBinding(RenderFrameHost* render_frame_host) = 0;
|
| + virtual RenderFrameHost* GetCurrentTargetFrame() = 0;
|
| + };
|
| +
|
| + // Generic helpers for the implementation to provide. See the templated
|
| + // AddFrameInterface and RemoveFrameInterface above.
|
| + virtual void AddFrameInterface(const std::string& name,
|
| + std::unique_ptr<FrameInterfaceBase> iface) = 0;
|
| + virtual void RemoveFrameInterface(const std::string& name) = 0;
|
| +
|
| + // Called immediately before any message or error is dispatched on behalf of
|
| + // any owned bindings.
|
| + virtual void WillDispatchForFrame(RenderFrameHost* render_frame_host) = 0;
|
| +
|
| + template <typename Interface>
|
| + class FrameInterface : public FrameInterfaceBase {
|
| + public:
|
| + FrameInterface(Interface* impl, WebContentsInterfaceRegistry* registry)
|
| + : impl_(impl), bindings_(mojo::BindingSetDispatchMode::WITH_CONTEXT) {
|
| + bindings_.set_pre_dispatch_handler(
|
| + base::Bind(&WebContentsInterfaceRegistry::WillDispatchForContext,
|
| + base::Unretained(registry)));
|
| + }
|
| +
|
| + ~FrameInterface() override {}
|
| +
|
| + void AddBinding(RenderFrameHost* render_frame_host,
|
| + mojo::ScopedInterfaceEndpointHandle handle) override {
|
| + mojo::AssociatedInterfaceRequest<Interface> request;
|
| + request.Bind(std::move(handle));
|
| + frame_binding_map_[render_frame_host].push_back(bindings_.AddBinding(
|
| + impl_, std::move(request), static_cast<void*>(render_frame_host)));
|
| + }
|
| +
|
| + void RemoveBinding(RenderFrameHost* render_frame_host) override {
|
| + auto it = frame_binding_map_.find(render_frame_host);
|
| + DCHECK(it != frame_binding_map_.end());
|
| + for (auto id : it->second)
|
| + bindings_.RemoveBinding(id);
|
| + frame_binding_map_.erase(it);
|
| + }
|
| +
|
| + RenderFrameHost* GetCurrentTargetFrame() override {
|
| + return static_cast<RenderFrameHost*>(bindings_.dispatch_context());
|
| + }
|
| +
|
| + private:
|
| + Interface* const impl_;
|
| + mojo::AssociatedBindingSet<Interface> bindings_;
|
| + std::map<RenderFrameHost*, std::vector<mojo::BindingId>> frame_binding_map_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(FrameInterface);
|
| + };
|
| +
|
| + private:
|
| + void WillDispatchForContext(void* context) {
|
| + WillDispatchForFrame(reinterpret_cast<RenderFrameHost*>(context));
|
| + }
|
| +};
|
| +
|
| +} // namespace content
|
| +
|
| +#endif // CONTENT_PUBLIC_BROWSER_WEB_CONTENTS_INTERFACE_REGISTRY_H_
|
|
|