1// Copyright 2014 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#include "base/memory/scoped_ptr.h" 6#include "dbus/bus.h" 7#include "dbus/exported_object.h" 8#include "dbus/message.h" 9#include "dbus/object_path.h" 10#include "mojo/embedder/channel_init.h" 11#include "mojo/public/cpp/application/application_connection.h" 12#include "mojo/public/cpp/application/application_delegate.h" 13#include "mojo/public/cpp/application/application_impl.h" 14#include "mojo/public/cpp/application/interface_factory.h" 15#include "mojo/public/cpp/bindings/interface_request.h" 16#include "mojo/shell/external_service.mojom.h" 17 18namespace mojo { 19const char kMojoDBusImplPath[] = "/org/chromium/MojoImpl"; 20const char kMojoDBusInterface[] = "org.chromium.Mojo"; 21const char kMojoDBusConnectMethod[] = "ConnectChannel"; 22 23class DBusExternalServiceBase { 24 public: 25 explicit DBusExternalServiceBase(const std::string& service_name); 26 virtual ~DBusExternalServiceBase(); 27 28 void Start(); 29 30 protected: 31 // TODO(cmasone): Enable multiple peers to connect/disconnect 32 virtual void Connect(ScopedMessagePipeHandle client_handle) = 0; 33 virtual void Disconnect() = 0; 34 35 private: 36 // Implementation of org.chromium.Mojo.ConnectChannel, exported over DBus. 37 // Takes a file descriptor and uses it to create a MessagePipe that is then 38 // hooked to an implementation of ExternalService. 39 void ConnectChannel(dbus::MethodCall* method_call, 40 dbus::ExportedObject::ResponseSender sender); 41 42 void ExportMethods(); 43 void InitializeDBus(); 44 void TakeDBusServiceOwnership(); 45 46 const std::string service_name_; 47 scoped_refptr<dbus::Bus> bus_; 48 dbus::ExportedObject* exported_object_; // Owned by bus_; 49 scoped_ptr<embedder::ChannelInit> channel_init_; 50 DISALLOW_COPY_AND_ASSIGN(DBusExternalServiceBase); 51}; 52 53template <class ServiceImpl> 54class DBusExternalService 55 : public DBusExternalServiceBase, 56 public ApplicationDelegate, 57 public InterfaceFactory<typename ServiceImpl::ImplementedInterface> { 58 public: 59 explicit DBusExternalService(const std::string& service_name) 60 : DBusExternalServiceBase(service_name) { 61 } 62 virtual ~DBusExternalService() {} 63 64 virtual bool ConfigureIncomingConnection(ApplicationConnection* connection) 65 MOJO_OVERRIDE { 66 connection->AddService(this); 67 return true; 68 } 69 70 virtual void Create( 71 ApplicationConnection* connection, 72 InterfaceRequest<typename ServiceImpl::ImplementedInterface> request) 73 MOJO_OVERRIDE { 74 BindToRequest(new ServiceImpl, &request); 75 } 76 77 protected: 78 virtual void Connect(ScopedMessagePipeHandle client_handle) OVERRIDE { 79 external_service_.reset(BindToPipe(new Impl(this), client_handle.Pass())); 80 } 81 82 virtual void Disconnect() OVERRIDE { 83 external_service_.reset(); 84 } 85 86 private: 87 class Impl : public InterfaceImpl<ExternalService> { 88 public: 89 explicit Impl(DBusExternalService* service) : service_(service) { 90 } 91 virtual void OnConnectionError() OVERRIDE { 92 service_->Disconnect(); 93 } 94 virtual void Activate(ScopedMessagePipeHandle service_provider_handle) 95 OVERRIDE { 96 app_.reset(new ApplicationImpl(service_, service_provider_handle.Pass())); 97 } 98 private: 99 DBusExternalService* service_; 100 scoped_ptr<Application> app_; 101 }; 102 103 scoped_ptr<Impl> external_service_; 104}; 105 106} // namespace mojo 107