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 "mojo/dbus/dbus_external_service.h" 6 7 #include "base/bind.h" 8 #include "base/callback.h" 9 #include "base/logging.h" 10 #include "base/memory/scoped_ptr.h" 11 #include "base/message_loop/message_loop_proxy.h" 12 #include "dbus/bus.h" 13 #include "dbus/exported_object.h" 14 #include "dbus/file_descriptor.h" 15 #include "dbus/message.h" 16 #include "dbus/object_path.h" 17 #include "mojo/embedder/channel_init.h" 18 #include "mojo/public/cpp/application/application.h" 19 #include "mojo/public/cpp/bindings/error_handler.h" 20 #include "mojo/public/interfaces/service_provider/service_provider.mojom.h" 21 #include "mojo/shell/external_service.mojom.h" 22 23 namespace mojo { 24 25 DBusExternalServiceBase::DBusExternalServiceBase( 26 const std::string& service_name) 27 : service_name_(service_name), 28 exported_object_(NULL) { 29 } 30 DBusExternalServiceBase::~DBusExternalServiceBase() {} 31 32 void DBusExternalServiceBase::Start() { 33 InitializeDBus(); 34 ExportMethods(); 35 TakeDBusServiceOwnership(); 36 DVLOG(1) << "External service started"; 37 } 38 39 void DBusExternalServiceBase::ConnectChannel( 40 dbus::MethodCall* method_call, 41 dbus::ExportedObject::ResponseSender sender) { 42 dbus::MessageReader reader(method_call); 43 dbus::FileDescriptor wrapped_fd; 44 if (!reader.PopFileDescriptor(&wrapped_fd)) { 45 sender.Run( 46 dbus::ErrorResponse::FromMethodCall( 47 method_call, 48 "org.chromium.Mojo.BadHandle", 49 "Invalid FD.").PassAs<dbus::Response>()); 50 return; 51 } 52 wrapped_fd.CheckValidity(); 53 channel_init_.reset(new mojo::embedder::ChannelInit); 54 mojo::ScopedMessagePipeHandle message_pipe = 55 channel_init_->Init(wrapped_fd.TakeValue(), 56 base::MessageLoopProxy::current()); 57 CHECK(message_pipe.is_valid()); 58 59 Connect(message_pipe.Pass()); 60 sender.Run(dbus::Response::FromMethodCall(method_call)); 61 } 62 63 void DBusExternalServiceBase::ExportMethods() { 64 CHECK(exported_object_); 65 CHECK(exported_object_->ExportMethodAndBlock( 66 kMojoDBusInterface, kMojoDBusConnectMethod, 67 base::Bind(&DBusExternalServiceBase::ConnectChannel, 68 base::Unretained(this)))); 69 } 70 71 void DBusExternalServiceBase::InitializeDBus() { 72 CHECK(!bus_); 73 dbus::Bus::Options options; 74 options.bus_type = dbus::Bus::SESSION; 75 bus_ = new dbus::Bus(options); 76 CHECK(bus_->Connect()); 77 CHECK(bus_->SetUpAsyncOperations()); 78 79 exported_object_ = 80 bus_->GetExportedObject(dbus::ObjectPath(kMojoDBusImplPath)); 81 } 82 83 void DBusExternalServiceBase::TakeDBusServiceOwnership() { 84 CHECK(bus_->RequestOwnershipAndBlock( 85 service_name_, 86 dbus::Bus::REQUIRE_PRIMARY_ALLOW_REPLACEMENT)) 87 << "Unable to take ownership of " << service_name_; 88 } 89 90 } // namespace mojo 91