1 //
2 // Copyright 2016 The Android Open Source Project
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at:
7 //
8 // http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16
17 #include "service/ipc/dbus/bluetooth_adapter.h"
18 #include <base/files/file_util.h>
19 #include <base/logging.h>
20 #include "service/hal/bluetooth_interface.h"
21
22 using ::dbus::Bus;
23 using ::dbus::ExportedObject;
24 using ::dbus::MethodCall;
25 using ::dbus::MessageWriter;
26 using ::dbus::Response;
27 using ::dbus::ObjectPath;
28 using ::dbus::ErrorResponse;
29
30 namespace {
31
32 const std::string kBluetoothAdapterInterface = "org.fluoride.BluetoothAdapter";
33 const std::string kEnable = "Enable";
34 const std::string kDisable = "Disable";
35 const std::string kBluetoothAdapter = "org.fluoride.BluetoothAdapter";
36 const std::string kBluetoothAdapterPath = "/org/fluoride/BluetoothAdapter";
37
38 // TODO(jpawlowski): right now xml interface files are in service/ipc/dbus/
39 // folder. Make a script to move them into /usr/share/dbus-1/interfaces
40 const char kBindingsPath[] =
41 "/usr/share/dbus-1/interfaces/org.fluoride.BluetoothAdapter.xml";
42 const char kDBusIntrospectMethod[] = "Introspect";
43
44 } // namespace
45
46 namespace ipc {
47 namespace dbus {
48
49 #if defined(BASE_VER) && BASE_VER > 780000
50 // New libchrome treats ResponseSender as base::OnceCallback so we need to move
51 // ownership before calling ::Run()
RunResponse(std::unique_ptr<Response> response,ExportedObject::ResponseSender & response_sender)52 inline void RunResponse(std::unique_ptr<Response> response,
53 ExportedObject::ResponseSender& response_sender) {
54 std::move(response_sender).Run(std::move(response));
55 }
56 #else
57 inline void RunResponse(std::unique_ptr<Response> response,
58 ExportedObject::ResponseSender& response_sender) {
59 response_sender.Run(std::move(response));
60 }
61 #endif
62
BluetoothAdapter(scoped_refptr<Bus> bus,bluetooth::Adapter * adapter)63 BluetoothAdapter::BluetoothAdapter(scoped_refptr<Bus> bus,
64 bluetooth::Adapter* adapter)
65 : adapter_(adapter) {
66 exported_object_ = bus->GetExportedObject(ObjectPath(kBluetoothAdapterPath));
67
68 CHECK(exported_object_->ExportMethodAndBlock(
69 kBluetoothAdapterInterface, kEnable,
70 base::Bind(&BluetoothAdapter::Enable, base::Unretained(this))));
71
72 CHECK(exported_object_->ExportMethodAndBlock(
73 kBluetoothAdapterInterface, kDisable,
74 base::Bind(&BluetoothAdapter::Disable, base::Unretained(this))));
75
76 CHECK(exported_object_->ExportMethodAndBlock(
77 DBUS_INTERFACE_INTROSPECTABLE, kDBusIntrospectMethod,
78 base::Bind(&BluetoothAdapter::Introspect, base::Unretained(this))));
79
80 CHECK(bus->RequestOwnershipAndBlock(kBluetoothAdapter, Bus::REQUIRE_PRIMARY))
81 << "Unable to take ownership of " << kBluetoothAdapter
82 << ". Make sure you have proper busconfig file "
83 "/etc/dbus-1/system.d/org.fluoride.conf";
84 }
85
Enable(MethodCall * method_call,ExportedObject::ResponseSender response_sender)86 void BluetoothAdapter::Enable(MethodCall* method_call,
87 ExportedObject::ResponseSender response_sender) {
88 VLOG(1) << __func__;
89 adapter_->Enable();
90 RunResponse(Response::FromMethodCall(method_call), response_sender);
91 }
92
Disable(MethodCall * method_call,ExportedObject::ResponseSender response_sender)93 void BluetoothAdapter::Disable(MethodCall* method_call,
94 ExportedObject::ResponseSender response_sender) {
95 VLOG(1) << __func__;
96 adapter_->Disable();
97 RunResponse(Response::FromMethodCall(method_call), response_sender);
98 }
99
Introspect(MethodCall * method_call,ExportedObject::ResponseSender response_sender)100 void BluetoothAdapter::Introspect(
101 MethodCall* method_call, ExportedObject::ResponseSender response_sender) {
102 VLOG(1) << __func__;
103
104 std::string output;
105 if (!base::ReadFileToString(base::FilePath(kBindingsPath), &output)) {
106 PLOG(ERROR) << "Can't read XML bindings from disk:";
107 RunResponse(ErrorResponse::FromMethodCall(
108 method_call, "Can't read XML bindings from disk.", ""),
109 response_sender);
110 }
111
112 std::unique_ptr<Response> response(Response::FromMethodCall(method_call));
113 MessageWriter writer(response.get());
114 writer.AppendString(output);
115
116 RunResponse(std::move(response), response_sender);
117 }
118
~BluetoothAdapter()119 BluetoothAdapter::~BluetoothAdapter() {}
120
121 } // namespace dbus
122 } // namespace ipc
123