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.h" 12 #include "mojo/public/interfaces/service_provider/service_provider.mojom.h" 13 #include "mojo/shell/external_service.mojom.h" 14 15 namespace mojo { 16 const char kMojoDBusImplPath[] = "/org/chromium/MojoImpl"; 17 const char kMojoDBusInterface[] = "org.chromium.Mojo"; 18 const char kMojoDBusConnectMethod[] = "ConnectChannel"; 19 20 class DBusExternalServiceBase { 21 public: 22 explicit DBusExternalServiceBase(const std::string& service_name); 23 virtual ~DBusExternalServiceBase(); 24 25 void Start(); 26 27 protected: 28 // TODO(cmasone): Enable multiple peers to connect/disconnect 29 virtual void Connect(ScopedMessagePipeHandle client_handle) = 0; 30 virtual void Disconnect() = 0; 31 32 private: 33 // Implementation of org.chromium.Mojo.ConnectChannel, exported over DBus. 34 // Takes a file descriptor and uses it to create a MessagePipe that is then 35 // hooked to an implementation of ExternalService. 36 void ConnectChannel(dbus::MethodCall* method_call, 37 dbus::ExportedObject::ResponseSender sender); 38 39 void ExportMethods(); 40 void InitializeDBus(); 41 void TakeDBusServiceOwnership(); 42 43 const std::string service_name_; 44 scoped_refptr<dbus::Bus> bus_; 45 dbus::ExportedObject* exported_object_; // Owned by bus_; 46 scoped_ptr<embedder::ChannelInit> channel_init_; 47 DISALLOW_COPY_AND_ASSIGN(DBusExternalServiceBase); 48 }; 49 50 template <class ServiceImpl> 51 class DBusExternalService : public DBusExternalServiceBase { 52 public: 53 explicit DBusExternalService(const std::string& service_name) 54 : DBusExternalServiceBase(service_name) { 55 } 56 virtual ~DBusExternalService() {} 57 58 protected: 59 virtual void Connect(ScopedMessagePipeHandle client_handle) OVERRIDE { 60 external_service_.reset(BindToPipe(new Impl(this), client_handle.Pass())); 61 } 62 63 virtual void Disconnect() OVERRIDE { 64 external_service_.reset(); 65 } 66 67 private: 68 class Impl : public InterfaceImpl<ExternalService> { 69 public: 70 explicit Impl(DBusExternalService* service) : service_(service) { 71 } 72 virtual void OnConnectionError() OVERRIDE { 73 service_->Disconnect(); 74 } 75 virtual void Activate(ScopedMessagePipeHandle service_provider_handle) 76 OVERRIDE { 77 app_.reset(new Application(service_provider_handle.Pass())); 78 app_->AddService<ServiceImpl>(); 79 } 80 private: 81 DBusExternalService* service_; 82 scoped_ptr<Application> app_; 83 }; 84 85 scoped_ptr<Impl> external_service_; 86 }; 87 88 } // namespace mojo 89