OLD | NEW |
(Empty) | |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #ifndef CONTENT_PUBLIC_BROWSER_WEB_CONTENTS_BINDING_SET_H_ |
| 6 #define CONTENT_PUBLIC_BROWSER_WEB_CONTENTS_BINDING_SET_H_ |
| 7 |
| 8 #include <memory> |
| 9 #include <string> |
| 10 |
| 11 #include "base/callback.h" |
| 12 #include "base/macros.h" |
| 13 #include "content/common/content_export.h" |
| 14 #include "content/public/browser/web_contents.h" |
| 15 #include "mojo/public/cpp/bindings/associated_binding_set.h" |
| 16 #include "mojo/public/cpp/bindings/associated_interface_request.h" |
| 17 #include "mojo/public/cpp/bindings/scoped_interface_endpoint_handle.h" |
| 18 |
| 19 namespace content { |
| 20 |
| 21 class RenderFrameHost; |
| 22 class WebContentsImpl; |
| 23 |
| 24 // Base class for something which owns a mojo::AssociatedBindingSet on behalf |
| 25 // of a WebContents. See WebContentsFrameBindingSet<T> below. |
| 26 class CONTENT_EXPORT WebContentsBindingSet { |
| 27 protected: |
| 28 class Binder { |
| 29 public: |
| 30 virtual ~Binder() {} |
| 31 |
| 32 virtual void OnRequestForFrame( |
| 33 RenderFrameHost* render_frame_host, |
| 34 mojo::ScopedInterfaceEndpointHandle handle); |
| 35 }; |
| 36 |
| 37 WebContentsBindingSet(WebContents* web_contents, |
| 38 const std::string& interface_name, |
| 39 std::unique_ptr<Binder> binder); |
| 40 ~WebContentsBindingSet(); |
| 41 |
| 42 private: |
| 43 friend class WebContentsImpl; |
| 44 |
| 45 void CloseAllBindings(); |
| 46 void OnRequestForFrame(RenderFrameHost* render_frame_host, |
| 47 mojo::ScopedInterfaceEndpointHandle handle); |
| 48 |
| 49 const base::Closure remove_callback_; |
| 50 std::unique_ptr<Binder> binder_; |
| 51 |
| 52 DISALLOW_COPY_AND_ASSIGN(WebContentsBindingSet); |
| 53 }; |
| 54 |
| 55 // Owns a set of Channel-associated interface bindings with frame context on |
| 56 // message dispatch. |
| 57 // |
| 58 // To use this, a |mojom::Foo| implementation need only own an instance of |
| 59 // WebContentsFrameBindingSet<mojom::Foo>. This allows remote RenderFrames to |
| 60 // acquire handles to the |mojom::Foo| interface via |
| 61 // RenderFrame::GetRemoteAssociatedInterfaces() and send messages here. When |
| 62 // messages are dispatched to the implementation, the implementation can call |
| 63 // GetCurrentTargetFrame() on this object (see below) to determine which |
| 64 // frame sent the message. |
| 65 // |
| 66 // For example: |
| 67 // |
| 68 // class FooImpl : public mojom::Foo { |
| 69 // public: |
| 70 // explicit FooImpl(WebContents* web_contents) |
| 71 // : web_contents_(web_contents), bindings_(web_contents, this) {} |
| 72 // |
| 73 // // mojom::Foo: |
| 74 // void DoFoo() override { |
| 75 // if (bindings_.GetCurrentTargetFrame() == web_contents_->GetMainFrame()) |
| 76 // ; // Do something interesting |
| 77 // } |
| 78 // |
| 79 // private: |
| 80 // WebContents* web_contents_; |
| 81 // WebContentsFrameBindingSet<mojom::Foo> bindings_; |
| 82 // }; |
| 83 // |
| 84 // When an instance of FooImpl is constructed over a WebContents, the mojom::Foo |
| 85 // interface will be exposed to all remote RenderFrame objects. If the |
| 86 // WebContents is destroyed at any point, the bindings will automatically reset |
| 87 // and will cease to dispatch further incoming messages. |
| 88 // |
| 89 // If FooImpl is destroyed first, the bindings are automatically removed and |
| 90 // future incoming interface requests for mojom::Foo will be rejected. |
| 91 // |
| 92 // Because this object uses Channel-associated interface bindings, all messages |
| 93 // sent via these interfaces are ordered with respect to legacy Chrome IPC |
| 94 // messages on the relevant IPC::Channel (i.e. the Channel between the browser |
| 95 // and whatever render process hosts the sending frame.) |
| 96 template <typename Interface> |
| 97 class WebContentsFrameBindingSet : public WebContentsBindingSet { |
| 98 public: |
| 99 WebContentsFrameBindingSet(WebContents* web_contents, Interface* impl) |
| 100 : WebContentsBindingSet( |
| 101 web_contents, Interface::Name_, |
| 102 base::MakeUnique<FrameInterfaceBinder>(this, impl)) {} |
| 103 ~WebContentsFrameBindingSet() {} |
| 104 |
| 105 // Returns the RenderFrameHost currently targeted by a message dispatch to |
| 106 // this interface. Must only be called during the extent of a message dispatch |
| 107 // for this interface. |
| 108 RenderFrameHost* GetCurrentTargetFrame() { |
| 109 DCHECK(current_target_frame_); |
| 110 return current_target_frame_; |
| 111 } |
| 112 |
| 113 void SetCurrentTargetFrameForTesting(RenderFrameHost* render_frame_host) { |
| 114 current_target_frame_ = render_frame_host; |
| 115 } |
| 116 |
| 117 private: |
| 118 class FrameInterfaceBinder : public Binder { |
| 119 public: |
| 120 FrameInterfaceBinder(WebContentsFrameBindingSet* binding_set, |
| 121 Interface* impl) |
| 122 : impl_(impl), bindings_(mojo::BindingSetDispatchMode::WITH_CONTEXT) { |
| 123 bindings_.set_pre_dispatch_handler( |
| 124 base::Bind(&WebContentsFrameBindingSet::WillDispatchForContext, |
| 125 base::Unretained(binding_set))); |
| 126 } |
| 127 |
| 128 ~FrameInterfaceBinder() override {} |
| 129 |
| 130 // Binder: |
| 131 void OnRequestForFrame( |
| 132 RenderFrameHost* render_frame_host, |
| 133 mojo::ScopedInterfaceEndpointHandle handle) override { |
| 134 mojo::AssociatedInterfaceRequest<Interface> request; |
| 135 request.Bind(std::move(handle)); |
| 136 bindings_.AddBinding(impl_, std::move(request), render_frame_host); |
| 137 } |
| 138 |
| 139 Interface* const impl_; |
| 140 mojo::AssociatedBindingSet<Interface> bindings_; |
| 141 |
| 142 DISALLOW_COPY_AND_ASSIGN(FrameInterfaceBinder); |
| 143 }; |
| 144 |
| 145 void WillDispatchForContext(void* context) { |
| 146 current_target_frame_ = static_cast<RenderFrameHost*>(context); |
| 147 } |
| 148 |
| 149 RenderFrameHost* current_target_frame_ = nullptr; |
| 150 |
| 151 DISALLOW_COPY_AND_ASSIGN(WebContentsFrameBindingSet); |
| 152 }; |
| 153 |
| 154 } // namespace content |
| 155 |
| 156 #endif // CONTENT_PUBLIC_BROWSER_WEB_CONTENTS_BINDING_SET_H_ |
OLD | NEW |