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 SERVICES_SHELL_PUBLIC_CPP_INTERFACE_REGISTRY_H_ | |
6 #define SERVICES_SHELL_PUBLIC_CPP_INTERFACE_REGISTRY_H_ | |
7 | |
8 #include <memory> | |
9 #include <queue> | |
10 #include <set> | |
11 #include <utility> | |
12 | |
13 #include "base/callback.h" | |
14 #include "base/memory/ptr_util.h" | |
15 #include "mojo/public/cpp/bindings/binding.h" | |
16 #include "services/shell/public/cpp/capabilities.h" | |
17 #include "services/shell/public/cpp/identity.h" | |
18 #include "services/shell/public/cpp/lib/callback_binder.h" | |
19 #include "services/shell/public/cpp/lib/interface_factory_binder.h" | |
20 #include "services/shell/public/interfaces/interface_provider.mojom.h" | |
21 | |
22 namespace shell { | |
23 class Connection; | |
24 class InterfaceBinder; | |
25 | |
26 // An implementation of mojom::InterfaceProvider that allows the user to | |
27 // register services to be exposed to another application. | |
28 // | |
29 // To use, define a class that implements your specific interface. Then | |
30 // implement an InterfaceFactory<Foo> that binds instances of FooImpl to | |
31 // InterfaceRequest<Foo>s and register that on the registry like this: | |
32 // | |
33 // registry.AddInterface(&factory); | |
34 // | |
35 // Or, if you have multiple factories implemented by the same type, explicitly | |
36 // specify the interface to register the factory for: | |
37 // | |
38 // registry.AddInterface<Foo>(&my_foo_and_bar_factory_); | |
39 // registry.AddInterface<Bar>(&my_foo_and_bar_factory_); | |
40 // | |
41 // The InterfaceFactory must outlive the InterfaceRegistry. | |
42 // | |
43 // Additionally you may specify a default InterfaceBinder to handle requests for | |
44 // interfaces unhandled by any registered InterfaceFactory. Just as with | |
45 // InterfaceFactory, the default InterfaceBinder supplied must outlive | |
46 // InterfaceRegistry. | |
47 // | |
48 class InterfaceRegistry : public mojom::InterfaceProvider { | |
49 public: | |
50 using Binder = base::Callback<void(const std::string&, | |
51 mojo::ScopedMessagePipeHandle)>; | |
52 | |
53 class TestApi { | |
54 public: | |
55 explicit TestApi(InterfaceRegistry* registry) : registry_(registry) {} | |
56 ~TestApi() {} | |
57 | |
58 void SetInterfaceBinderForName(InterfaceBinder* binder, | |
59 const std::string& interface_name) { | |
60 registry_->SetInterfaceBinderForName( | |
61 base::WrapUnique(binder), interface_name); | |
62 } | |
63 | |
64 template <typename Interface> | |
65 void GetLocalInterface(mojo::InterfaceRequest<Interface> request) { | |
66 GetLocalInterface(Interface::Name_, request.PassMessagePipe()); | |
67 } | |
68 | |
69 void GetLocalInterface(const std::string& name, | |
70 mojo::ScopedMessagePipeHandle handle) { | |
71 registry_->GetInterface(name, std::move(handle)); | |
72 } | |
73 | |
74 private: | |
75 InterfaceRegistry* registry_; | |
76 DISALLOW_COPY_AND_ASSIGN(TestApi); | |
77 }; | |
78 | |
79 // Construct an InterfaceRegistry with no filtering rules applied. | |
80 InterfaceRegistry(); | |
81 | |
82 // Construct an InterfaceRegistry in |local_identity| that exposes only | |
83 // |allowed_interfaces| to |remote_identity|. | |
84 InterfaceRegistry(const Identity& local_identity, | |
85 const Identity& remote_identity, | |
86 const Interfaces& allowed_interfaces); | |
87 ~InterfaceRegistry() override; | |
88 | |
89 // Sets a default handler for incoming interface requests which are allowed by | |
90 // capability filters but have no registered handler in this registry. | |
91 void set_default_binder(const Binder& binder) { default_binder_ = binder; } | |
92 | |
93 void Bind(mojom::InterfaceProviderRequest local_interfaces_request); | |
94 | |
95 base::WeakPtr<InterfaceRegistry> GetWeakPtr(); | |
96 | |
97 // Allows |Interface| to be exposed via this registry. Requests to bind will | |
98 // be handled by |factory|. Returns true if the interface was exposed, false | |
99 // if Connection policy prevented exposure. | |
100 template <typename Interface> | |
101 bool AddInterface(InterfaceFactory<Interface>* factory) { | |
102 return SetInterfaceBinderForName( | |
103 base::MakeUnique<internal::InterfaceFactoryBinder<Interface>>(factory), | |
104 Interface::Name_); | |
105 } | |
106 | |
107 // Like AddInterface above, except supplies a callback to bind the MP instead | |
108 // of an InterfaceFactory, and optionally provides a task runner where the | |
109 // callback will be run. | |
110 template <typename Interface> | |
111 bool AddInterface( | |
112 const base::Callback<void(mojo::InterfaceRequest<Interface>)>& callback, | |
113 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner = | |
114 nullptr) { | |
115 return SetInterfaceBinderForName( | |
116 base::MakeUnique<internal::CallbackBinder<Interface>>(callback, | |
117 task_runner), | |
118 Interface::Name_); | |
119 } | |
120 bool AddInterface( | |
121 const std::string& name, | |
122 const base::Callback<void(mojo::ScopedMessagePipeHandle)>& callback, | |
123 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner = | |
124 nullptr); | |
125 | |
126 template <typename Interface> | |
127 void RemoveInterface() { | |
128 RemoveInterface(Interface::Name_); | |
129 } | |
130 void RemoveInterface(const std::string& name); | |
131 | |
132 // Temporarily prevent incoming interface requests from being bound. Incoming | |
133 // requests will be queued internally and dispatched once ResumeBinding() is | |
134 // called. | |
135 void PauseBinding(); | |
136 | |
137 // Resumes incoming interface request binding. | |
138 void ResumeBinding(); | |
139 | |
140 // Populates a set with the interface names this registry can bind. | |
141 void GetInterfaceNames(std::set<std::string>* interface_names); | |
142 | |
143 // Sets a closure to be run when the InterfaceProvider pipe is closed. | |
144 void SetConnectionLostClosure(const base::Closure& connection_lost_closure); | |
145 | |
146 private: | |
147 using NameToInterfaceBinderMap = | |
148 std::map<std::string, std::unique_ptr<InterfaceBinder>>; | |
149 | |
150 // mojom::InterfaceProvider: | |
151 void GetInterface(const std::string& interface_name, | |
152 mojo::ScopedMessagePipeHandle handle) override; | |
153 | |
154 // Returns true if the binder was set, false if it was not set (e.g. by | |
155 // some filtering policy preventing this interface from being exposed). | |
156 bool SetInterfaceBinderForName(std::unique_ptr<InterfaceBinder> binder, | |
157 const std::string& name); | |
158 | |
159 // Returns true if |remote_identity_| is allowed to bind |interface_name|, | |
160 // according to capability policy. | |
161 bool CanBindRequestForInterface(const std::string& interface_name) const; | |
162 | |
163 mojom::InterfaceProviderRequest pending_request_; | |
164 | |
165 mojo::Binding<mojom::InterfaceProvider> binding_; | |
166 const Identity local_identity_; | |
167 const Identity remote_identity_; | |
168 const Interfaces allowed_interfaces_; | |
169 const bool allow_all_interfaces_; | |
170 | |
171 NameToInterfaceBinderMap name_to_binder_; | |
172 Binder default_binder_; | |
173 | |
174 bool is_paused_ = false; | |
175 | |
176 // Pending interface requests which can accumulate if GetInterface() is called | |
177 // while binding is paused. | |
178 std::queue<std::pair<std::string, mojo::ScopedMessagePipeHandle>> | |
179 pending_interface_requests_; | |
180 | |
181 base::WeakPtrFactory<InterfaceRegistry> weak_factory_; | |
182 | |
183 DISALLOW_COPY_AND_ASSIGN(InterfaceRegistry); | |
184 }; | |
185 | |
186 } // namespace shell | |
187 | |
188 #endif // SERVICES_SHELL_PUBLIC_CPP_INTERFACE_REGISTRY_H_ | |
OLD | NEW |