| Index: headless/public/headless_web_contents.h | 
| diff --git a/headless/public/headless_web_contents.h b/headless/public/headless_web_contents.h | 
| index a193d5042e6932a42330ef9edca24d54eb54ce9d..777bb74b1a82d0c696ec090ad1649f4cab364c43 100644 | 
| --- a/headless/public/headless_web_contents.h | 
| +++ b/headless/public/headless_web_contents.h | 
| @@ -5,9 +5,12 @@ | 
| #ifndef HEADLESS_PUBLIC_HEADLESS_WEB_CONTENTS_H_ | 
| #define HEADLESS_PUBLIC_HEADLESS_WEB_CONTENTS_H_ | 
|  | 
| -#include "base/callback.h" | 
| +#include <list> | 
| + | 
| +#include "base/bind.h" | 
| #include "base/macros.h" | 
| #include "headless/public/headless_export.h" | 
| +#include "mojo/public/cpp/bindings/interface_request.h" | 
| #include "ui/gfx/geometry/size.h" | 
| #include "url/gurl.h" | 
|  | 
| @@ -82,6 +85,28 @@ class HEADLESS_EXPORT HeadlessWebContents::Builder { | 
| // outlive this HeadlessWebContents. | 
| Builder& SetBrowserContext(HeadlessBrowserContext* browser_context); | 
|  | 
| +  // Specify an embedder provided Mojo service to be installed.  The | 
| +  // |service_factory| callback is called on demand by Mojo to instantiate the | 
| +  // service if any client asks for it.  Note if JS bindings are used they are | 
| +  // assumed to be in their default location gen/path_to/filenme.mojom.js | 
| +  template <typename Interface> | 
| +  Builder& AddMojoService( | 
| +      const base::Callback<void(mojo::InterfaceRequest<Interface>)>& | 
| +          service_factory) { | 
| +    return AddMojoService( | 
| +        Interface::Name_, | 
| +        base::Bind(&Builder::ForwardToServiceFactory<Interface>, | 
| +                   service_factory)); | 
| +  } | 
| +  Builder& AddMojoService(const std::string& service_name, | 
| +                          const base::Callback<void( | 
| +                              mojo::ScopedMessagePipeHandle)>& service_factory); | 
| + | 
| +  // Specify JS mojo module bindings to be installed, one per mojom file. | 
| +  // Note a single mojom file could potentially define many interfaces. | 
| +  Builder& AddJsMojoBindings(const std::string& mojom_name, | 
| +                             const std::string& js_bindings); | 
| + | 
| // The returned object is owned by HeadlessBrowser. Call | 
| // HeadlessWebContents::Close() to dispose it. | 
| HeadlessWebContents* Build(); | 
| @@ -90,12 +115,48 @@ class HEADLESS_EXPORT HeadlessWebContents::Builder { | 
| friend class HeadlessBrowserImpl; | 
| friend class HeadlessWebContentsImpl; | 
|  | 
| +  template <typename Interface> | 
| +  static void ForwardToServiceFactory( | 
| +      const base::Callback<void(mojo::InterfaceRequest<Interface>)>& | 
| +          service_factory, | 
| +      mojo::ScopedMessagePipeHandle handle) { | 
| +    service_factory.Run(mojo::MakeRequest<Interface>(std::move(handle))); | 
| +  } | 
| + | 
| +  struct MojoService { | 
| +    MojoService(); | 
| +    MojoService(const std::string& service_name, | 
| +                const base::Callback<void(mojo::ScopedMessagePipeHandle)>& | 
| +                    service_factory); | 
| +    ~MojoService(); | 
| + | 
| +    std::string service_name; | 
| +    base::Callback<void(mojo::ScopedMessagePipeHandle)> service_factory; | 
| + | 
| +   private: | 
| +    DISALLOW_COPY_AND_ASSIGN(MojoService); | 
| +  }; | 
| + | 
| +  struct MojoBindings { | 
| +    MojoBindings(); | 
| +    MojoBindings(const std::string& mojom_name, const std::string& js_bindings); | 
| +    ~MojoBindings(); | 
| + | 
| +    std::string mojom_name; | 
| +    std::string js_bindings; | 
| + | 
| +   private: | 
| +    DISALLOW_COPY_AND_ASSIGN(MojoBindings); | 
| +  }; | 
| + | 
| explicit Builder(HeadlessBrowserImpl* browser); | 
|  | 
| HeadlessBrowserImpl* browser_; | 
| GURL initial_url_ = GURL("about:blank"); | 
| gfx::Size window_size_ = gfx::Size(800, 600); | 
| HeadlessBrowserContext* browser_context_; | 
| +  std::list<MojoService> mojo_services_; | 
| +  std::list<MojoBindings> mojo_bindings_; | 
|  | 
| DISALLOW_COPY_AND_ASSIGN(Builder); | 
| }; | 
|  |