1010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 2010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// found in the LICENSE file. 4010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 5010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "mojo/dbus/dbus_external_service.h" 6010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 7010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "base/bind.h" 8010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "base/callback.h" 9010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "base/logging.h" 10010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "base/memory/scoped_ptr.h" 11010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "base/message_loop/message_loop_proxy.h" 12010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "dbus/bus.h" 13010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "dbus/exported_object.h" 14010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "dbus/file_descriptor.h" 15010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "dbus/message.h" 16010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "dbus/object_path.h" 176d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)#include "mojo/embedder/channel_init.h" 18010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "mojo/public/cpp/bindings/error_handler.h" 19010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "mojo/shell/external_service.mojom.h" 20010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 21010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)namespace mojo { 22010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 23010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)DBusExternalServiceBase::DBusExternalServiceBase( 24010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const std::string& service_name) 25010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) : service_name_(service_name), 26010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) exported_object_(NULL) { 27010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 28010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)DBusExternalServiceBase::~DBusExternalServiceBase() {} 29010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 30010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void DBusExternalServiceBase::Start() { 31010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) InitializeDBus(); 32010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ExportMethods(); 33010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) TakeDBusServiceOwnership(); 34010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) DVLOG(1) << "External service started"; 35010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 36010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 37010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void DBusExternalServiceBase::ConnectChannel( 38010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) dbus::MethodCall* method_call, 39010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) dbus::ExportedObject::ResponseSender sender) { 40010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) dbus::MessageReader reader(method_call); 41010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) dbus::FileDescriptor wrapped_fd; 42010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (!reader.PopFileDescriptor(&wrapped_fd)) { 43010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) sender.Run( 44010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) dbus::ErrorResponse::FromMethodCall( 45010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) method_call, 46010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) "org.chromium.Mojo.BadHandle", 47010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) "Invalid FD.").PassAs<dbus::Response>()); 48010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return; 49010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 50010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) wrapped_fd.CheckValidity(); 516d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) channel_init_.reset(new mojo::embedder::ChannelInit); 52010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) mojo::ScopedMessagePipeHandle message_pipe = 53010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) channel_init_->Init(wrapped_fd.TakeValue(), 54010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) base::MessageLoopProxy::current()); 55010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) CHECK(message_pipe.is_valid()); 56010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 570de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) Connect(message_pipe.Pass()); 58010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) sender.Run(dbus::Response::FromMethodCall(method_call)); 59010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 60010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 61010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void DBusExternalServiceBase::ExportMethods() { 62010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) CHECK(exported_object_); 63010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) CHECK(exported_object_->ExportMethodAndBlock( 64010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) kMojoDBusInterface, kMojoDBusConnectMethod, 65010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) base::Bind(&DBusExternalServiceBase::ConnectChannel, 66010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) base::Unretained(this)))); 67010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 68010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 69010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void DBusExternalServiceBase::InitializeDBus() { 701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci CHECK(!bus_.get()); 71010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) dbus::Bus::Options options; 72010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) options.bus_type = dbus::Bus::SESSION; 73010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) bus_ = new dbus::Bus(options); 74010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) CHECK(bus_->Connect()); 75010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) CHECK(bus_->SetUpAsyncOperations()); 76010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 77010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) exported_object_ = 78010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) bus_->GetExportedObject(dbus::ObjectPath(kMojoDBusImplPath)); 79010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 80010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 81010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void DBusExternalServiceBase::TakeDBusServiceOwnership() { 82010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) CHECK(bus_->RequestOwnershipAndBlock( 83010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) service_name_, 84010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) dbus::Bus::REQUIRE_PRIMARY_ALLOW_REPLACEMENT)) 85010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) << "Unable to take ownership of " << service_name_; 86010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 87010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 88010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} // namespace mojo 89