Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7ccaa9fe authored by Jakub Pawlowski's avatar Jakub Pawlowski
Browse files

Initial DBus transport support

This patch adds initial support for DBus transport on Linux. It exposes
initial implementation of Adapter that can be Enabled and Disabled. One
can also introspect the interface to find the exposed methods. Further
patches will extend it's functionality.

Test: ninja -C out/Default -j 40
Change-Id: I173cc752b8d8aaa8706ed36f75f5a043cc987b1a
parent d05b1e21
Loading
Loading
Loading
Loading
+26 −0
Original line number Diff line number Diff line
@@ -201,6 +201,20 @@ source_set("base_sources") {
    "base/tracking_info.cc",
    "base/values.cc",
    "base/vlog.cc",

    "dbus/bus.cc",
    "dbus/dbus_statistics.cc",
    "dbus/exported_object.cc",
    "dbus/file_descriptor.cc",
    "dbus/message.cc",
    "dbus/object_manager.cc",
    "dbus/object_path.cc",
    "dbus/object_proxy.cc",
    "dbus/property.cc",
    "dbus/scoped_dbus_error.cc",
    "dbus/string_util.cc",
    "dbus/util.cc",
    "dbus/values_util.cc"
  ]

  defines = [
@@ -219,7 +233,13 @@ source_set("base_sources") {
    "//third_party/libevent",
    "//third_party/libevent/include",
    "//third_party/libchrome/base",
    "//third_party/libchrome/dbus",
    "//third_party/modp_b64",

    # paths to dbus headers, can be obtained by "pkg-config --cflags dbus-1"
    #TODO(jpawlowski) use pkg-config script like build/config/linux/pkg_config.gni
    "/usr/include/dbus-1.0/",
    "/usr/lib/x86_64-linux-gnu/dbus-1.0/include",
  ]
}

@@ -228,6 +248,11 @@ config("libchrome_config") {
  include_dirs = [
    "//third_party/googletest/googletest/include",
    "//third_party/libchrome",

    # paths to dbus headers, can be obtained by "pkg-config --cflags dbus-1"
    #TODO(jpawlowski) use pkg-config script like build/config/linux/pkg_config.gni
    "/usr/include/dbus-1.0/",
    "/usr/lib/x86_64-linux-gnu/dbus-1.0/include",
 ]
}

@@ -252,6 +277,7 @@ static_library("base") {
    "-levent",
    "-levent_core",
    "-lpthread",
    "-ldbus-1",
  ]

  public_configs = [ ":libchrome_config" ]
+2 −0
Original line number Diff line number Diff line
@@ -35,6 +35,8 @@ source_set("service") {
    "gatt_server_old.cc",
    "hal/bluetooth_gatt_interface.cc",
    "hal/bluetooth_interface.cc",
    "ipc/dbus/bluetooth_adapter.cc",
    "ipc/dbus/ipc_handler_dbus.cc",
    "hal/fake_bluetooth_gatt_interface.cc",
    "hal/fake_bluetooth_interface.cc",
    "ipc/ipc_handler.cc",
+11 −1
Original line number Diff line number Diff line
@@ -86,10 +86,20 @@ class DaemonImpl : public Daemon {
        LOG(ERROR) << "Failed to set up UNIX domain-socket IPCManager";
        return false;
      }
    } else if (!ipc_manager_->Start(ipc::IPCManager::TYPE_BINDER, nullptr)) {
      return true;
    }

#if !defined(OS_GENERIC)
    if (!ipc_manager_->Start(ipc::IPCManager::TYPE_BINDER, nullptr)) {
      LOG(ERROR) << "Failed to set up Binder IPCManager";
      return false;
    }
#else
    if (!ipc_manager_->Start(ipc::IPCManager::TYPE_DBUS, nullptr)) {
      LOG(ERROR) << "Failed to set up DBus IPCManager";
      return false;
    }
#endif

    return true;
  }
+107 −0
Original line number Diff line number Diff line
//
//  Copyright (C) 2016 The Android Open Source Project
//
//  Licensed under the Apache License, Version 2.0 (the "License");
//  you may not use this file except in compliance with the License.
//  You may obtain a copy of the License at:
//
//  http://www.apache.org/licenses/LICENSE-2.0
//
//  Unless required by applicable law or agreed to in writing, software
//  distributed under the License is distributed on an "AS IS" BASIS,
//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//  See the License for the specific language governing permissions and
//  limitations under the License.
//

#include "service/ipc/dbus/bluetooth_adapter.h"
#include <base/files/file_util.h>
#include <base/logging.h>
#include "service/common/bluetooth/util/address_helper.h"
#include "service/hal/bluetooth_interface.h"

using ::dbus::Bus;
using ::dbus::ExportedObject;
using ::dbus::MethodCall;
using ::dbus::MessageWriter;
using ::dbus::Response;
using ::dbus::ObjectPath;
using ::dbus::ErrorResponse;

namespace {

const std::string kBluetoothAdapterInterface = "org.fluoride.BluetoothAdapter";
const std::string kEnable = "Enable";
const std::string kDisable = "Disable";
const std::string kBluetoothAdapter = "org.fluoride.BluetoothAdapter";
const std::string kBluetoothAdapterPath = "/org/fluoride/BluetoothAdapter";

// TODO(jpawlowski): right now xml interface files are in service/ipc/dbus/
// folder.  Make a script to move them into /usr/share/dbus-1/interfaces
const char kBindingsPath[] =
    "/usr/share/dbus-1/interfaces/org.fluoride.BluetoothAdapter.xml";
const char kDBusIntrospectMethod[] = "Introspect";

}  // namespace

namespace ipc {
namespace dbus {

BluetoothAdapter::BluetoothAdapter(scoped_refptr<Bus> bus,
                                   bluetooth::Adapter* adapter)
    : adapter_(adapter) {
  exported_object_ = bus->GetExportedObject(ObjectPath(kBluetoothAdapterPath));

  CHECK(exported_object_->ExportMethodAndBlock(
      kBluetoothAdapterInterface, kEnable,
      base::Bind(&BluetoothAdapter::Enable, base::Unretained(this))));

  CHECK(exported_object_->ExportMethodAndBlock(
      kBluetoothAdapterInterface, kDisable,
      base::Bind(&BluetoothAdapter::Disable, base::Unretained(this))));

  CHECK(exported_object_->ExportMethodAndBlock(
      DBUS_INTERFACE_INTROSPECTABLE, kDBusIntrospectMethod,
      base::Bind(&BluetoothAdapter::Introspect, base::Unretained(this))));

  CHECK(bus->RequestOwnershipAndBlock(kBluetoothAdapter, Bus::REQUIRE_PRIMARY))
      << "Unable to take ownership of " << kBluetoothAdapter
      << ". Make sure you have proper busconfig file "
         "/etc/dbus-1/system.d/org.fluoride.conf";
}

void BluetoothAdapter::Enable(MethodCall* method_call,
                              ExportedObject::ResponseSender response_sender) {
  VLOG(1) << __func__;
  adapter_->Enable(false);
  response_sender.Run(Response::FromMethodCall(method_call));
}

void BluetoothAdapter::Disable(MethodCall* method_call,
                               ExportedObject::ResponseSender response_sender) {
  VLOG(1) << __func__;
  adapter_->Disable();
  response_sender.Run(Response::FromMethodCall(method_call));
}

void BluetoothAdapter::Introspect(
    MethodCall* method_call, ExportedObject::ResponseSender response_sender) {
  VLOG(1) << __func__;

  std::string output;
  if (!base::ReadFileToString(base::FilePath(kBindingsPath), &output)) {
    PLOG(ERROR) << "Can't read XML bindings from disk:";
    response_sender.Run(ErrorResponse::FromMethodCall(
        method_call, "Can't read XML bindings from disk.", ""));
  }
  std::unique_ptr<Response> response(Response::FromMethodCall(method_call));
  MessageWriter writer(response.get());
  writer.AppendString(output);

  response_sender.Run(std::move(response));
}

BluetoothAdapter::~BluetoothAdapter() {}

}  // namespace dbus
}  // namespace ipc
+56 −0
Original line number Diff line number Diff line
//
//  Copyright (C) 2016 The Android Open Source Project
//
//  Licensed under the Apache License, Version 2.0 (the "License");
//  you may not use this file except in compliance with the License.
//  You may obtain a copy of the License at:
//
//  http://www.apache.org/licenses/LICENSE-2.0
//
//  Unless required by applicable law or agreed to in writing, software
//  distributed under the License is distributed on an "AS IS" BASIS,
//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//  See the License for the specific language governing permissions and
//  limitations under the License.
//

#pragma once

#include "service/adapter.h"

#include <base/memory/ref_counted.h>
#include <dbus/bus.h>
#include <dbus/exported_object.h>
#include <dbus/message.h>
#include <dbus/object_path.h>
#include <dbus/property.h>

using ::dbus::Bus;
using ::dbus::ExportedObject;
using ::dbus::MethodCall;

namespace ipc {
namespace dbus {

class BluetoothAdapter {
 public:
  explicit BluetoothAdapter(scoped_refptr<Bus> bus,
                            bluetooth::Adapter* adapter);
  virtual ~BluetoothAdapter();

  void Enable(MethodCall* method_call,
              ExportedObject::ResponseSender response_sender);

  void Disable(MethodCall* method_call,
               ExportedObject::ResponseSender response_sender);

  void Introspect(MethodCall* method_call,
                  ExportedObject::ResponseSender response_sender);

 private:
  ExportedObject* exported_object_;
  bluetooth::Adapter* adapter_;
};

}  // namespace dbus
}  // namespace ipc
Loading