"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 = [
"//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",
]
}
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",
]
}
"-levent",
"-levent_core",
"-lpthread",
+ "-ldbus-1",
]
public_configs = [ ":libchrome_config" ]
"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",
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;
}
--- /dev/null
+//
+// 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
--- /dev/null
+//
+// 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
--- /dev/null
+//
+// 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/ipc_handler_dbus.h"
+
+#include <base/bind.h>
+#include <base/threading/thread_task_runner_handle.h>
+#include <dbus/bus.h>
+#include "service/daemon.h"
+#include "service/ipc/dbus/bluetooth_adapter.h"
+
+using dbus::Bus;
+
+namespace ipc {
+
+IPCHandlerDBus::IPCHandlerDBus(bluetooth::Adapter* adapter,
+ IPCManager::Delegate* delegate)
+ : IPCHandler(adapter, delegate) {}
+
+IPCHandlerDBus::~IPCHandlerDBus() {}
+
+bool IPCHandlerDBus::Run() {
+ LOG(INFO) << __func__;
+
+ dbus_thread_ = new base::Thread("D-Bus Thread");
+ base::Thread::Options thread_options;
+ thread_options.message_loop_type = base::MessageLoop::TYPE_IO;
+ dbus_thread_->StartWithOptions(thread_options);
+
+ dbus_thread_->task_runner()->PostTask(
+ FROM_HERE, base::Bind(&IPCHandlerDBus::InitDbus, base::Unretained(this)));
+
+ return true;
+}
+
+void IPCHandlerDBus::InitDbus() {
+ LOG(INFO) << __func__;
+
+ Bus::Options bus_options;
+ bus_options.bus_type = Bus::SYSTEM;
+ bus_options.connection_type = Bus::PRIVATE;
+ bus_options.dbus_task_runner = base::ThreadTaskRunnerHandle::Get();
+
+ scoped_refptr<Bus> bus_ = new Bus(bus_options);
+
+ ipc::dbus::BluetoothAdapter* bluetooth_adapter =
+ new ipc::dbus::BluetoothAdapter(bus_, adapter());
+
+ LOG(INFO) << __func__ << ": all services added";
+}
+
+void IPCHandlerDBus::Stop() { dbus_thread_->Stop(); }
+
+} // namespace ipc
--- /dev/null
+//
+// 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 <base/threading/thread.h>
+#include "service/ipc/ipc_handler.h"
+#include "service/ipc/ipc_manager.h"
+
+namespace base {
+class SingleThreadTaskRunner;
+} // namespace base
+
+namespace ipc {
+
+// Implements a DBus based IPCHandler
+class IPCHandlerDBus : public IPCHandler {
+ public:
+ IPCHandlerDBus(bluetooth::Adapter* adapter, IPCManager::Delegate* delegate);
+ ~IPCHandlerDBus() override;
+
+ void InitDbus();
+
+ // IPCHandler overrides:
+ bool Run() override;
+ void Stop() override;
+
+ private:
+ base::Thread* dbus_thread_;
+
+ IPCHandlerDBus() = default;
+
+ DISALLOW_COPY_AND_ASSIGN(IPCHandlerDBus);
+};
+
+} // namespace ipc
--- /dev/null
+<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
+ "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
+<node name="/org/chromium/SessionManager"
+ xmlns:doc="http://www.freedesktop.org/dbus/1.0/doc.dtd">
+
+ <!--
+ org.fluoride.BluetoothAdapter:
+ @short_description: Bluetooth adapter manager.
+
+ Interface for user bluetooth adapter. Right now allows only to enable
+ and disable the adapter.
+ -->
+ <interface name="org.fluoride.BluetoothAdapter">
+ <!--
+ Enable:
+
+ Enable the bluetooth adapter.
+ -->
+ <method name="Enable"></method>
+
+ <!--
+ Disable:
+
+ Disable the bluetooth adapter.
+ -->
+ <method name="Disable"></method>
+ </interface>
+</node>
\ No newline at end of file
#if !defined(OS_GENERIC)
#include "service/ipc/binder/ipc_handler_binder.h"
+#else
+#include "service/ipc/dbus/ipc_handler_dbus.h"
#endif // !defined(OS_GENERIC)
#include "service/ipc/ipc_handler_linux.h"
// holding a reference to them. Instead, explicitly stop them here.
if (BinderStarted()) binder_handler_->Stop();
if (LinuxStarted()) linux_handler_->Stop();
+ if (DBusStarted()) dbus_handler_->Stop();
}
bool IPCManager::Start(Type type, Delegate* delegate) {
return false;
}
return true;
+
#if !defined(OS_GENERIC)
case TYPE_BINDER:
if (BinderStarted()) {
return false;
}
return true;
+#else
+ case TYPE_DBUS:
+ if (DBusStarted()) {
+ LOG(ERROR) << "IPCManagerDBus already started.";
+ return false;
+ }
+
+ dbus_handler_ = new IPCHandlerDBus(adapter_, delegate);
+ if (!dbus_handler_->Run()) {
+ dbus_handler_ = nullptr;
+ return false;
+ }
+ return true;
#endif // !defined(OS_GENERIC)
+
default:
LOG(ERROR) << "Unsupported IPC type given: " << type;
}
bool IPCManager::LinuxStarted() const { return linux_handler_.get(); }
+bool IPCManager::DBusStarted() const { return dbus_handler_.get(); }
+
} // namespace ipc
public:
// Possible IPC types.
enum Type {
- TYPE_LINUX, // IPC based on a Linux sequential packet domain socket
- TYPE_BINDER // IPC based on the Binder
+ TYPE_LINUX, // IPC based on a Linux sequential packet domain socket
+ TYPE_BINDER, // IPC based on the Binder
+ TYPE_DBUS // IPC based on the DBus
};
// Interface for observing events from an IPC mechanism. These methods will be
// Returns true if an IPC type has been initialized.
bool BinderStarted() const;
bool LinuxStarted() const;
+ bool DBusStarted() const;
private:
IPCManager() = default;
// owned by us.
scoped_refptr<IPCHandler> binder_handler_;
scoped_refptr<IPCHandler> linux_handler_;
+ scoped_refptr<IPCHandler> dbus_handler_;
// The Bluetooth adapter instance. This is owned by Daemon so we keep a raw
// pointer to it.