Fix compilation error triggered with -Werror=sign-compare
[chromium-blink-merge.git] / chromeos / dbus / bluetooth_profile_service_provider.cc
blobe30fadaaf5f99be5aa14a92f46d4353c68591093
1 // Copyright 2013 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.
5 #include "chromeos/dbus/bluetooth_profile_service_provider.h"
7 #include <string>
9 #include "base/bind.h"
10 #include "base/logging.h"
11 #include "base/memory/ref_counted.h"
12 #include "base/sys_info.h"
13 #include "base/threading/platform_thread.h"
14 #include "chromeos/dbus/fake_bluetooth_profile_service_provider.h"
15 #include "dbus/bus.h"
16 #include "dbus/exported_object.h"
17 #include "dbus/message.h"
18 #include "dbus/object_path.h"
19 #include "third_party/cros_system_api/dbus/service_constants.h"
21 namespace chromeos {
23 // The BluetoothProfileServiceProvider implementation used in production.
24 class BluetoothProfileServiceProviderImpl
25 : public BluetoothProfileServiceProvider {
26 public:
27 BluetoothProfileServiceProviderImpl(dbus::Bus* bus,
28 const dbus::ObjectPath& object_path,
29 Delegate* delegate)
30 : origin_thread_id_(base::PlatformThread::CurrentId()),
31 bus_(bus),
32 delegate_(delegate),
33 object_path_(object_path),
34 weak_ptr_factory_(this) {
35 VLOG(1) << "Creating Bluetooth Profile: " << object_path_.value();
37 exported_object_ = bus_->GetExportedObject(object_path_);
39 exported_object_->ExportMethod(
40 bluetooth_profile::kBluetoothProfileInterface,
41 bluetooth_profile::kRelease,
42 base::Bind(&BluetoothProfileServiceProviderImpl::Release,
43 weak_ptr_factory_.GetWeakPtr()),
44 base::Bind(&BluetoothProfileServiceProviderImpl::OnExported,
45 weak_ptr_factory_.GetWeakPtr()));
47 exported_object_->ExportMethod(
48 bluetooth_profile::kBluetoothProfileInterface,
49 bluetooth_profile::kNewConnection,
50 base::Bind(&BluetoothProfileServiceProviderImpl::NewConnection,
51 weak_ptr_factory_.GetWeakPtr()),
52 base::Bind(&BluetoothProfileServiceProviderImpl::OnExported,
53 weak_ptr_factory_.GetWeakPtr()));
55 exported_object_->ExportMethod(
56 bluetooth_profile::kBluetoothProfileInterface,
57 bluetooth_profile::kRequestDisconnection,
58 base::Bind(&BluetoothProfileServiceProviderImpl::RequestDisconnection,
59 weak_ptr_factory_.GetWeakPtr()),
60 base::Bind(&BluetoothProfileServiceProviderImpl::OnExported,
61 weak_ptr_factory_.GetWeakPtr()));
63 exported_object_->ExportMethod(
64 bluetooth_profile::kBluetoothProfileInterface,
65 bluetooth_profile::kCancel,
66 base::Bind(&BluetoothProfileServiceProviderImpl::Cancel,
67 weak_ptr_factory_.GetWeakPtr()),
68 base::Bind(&BluetoothProfileServiceProviderImpl::OnExported,
69 weak_ptr_factory_.GetWeakPtr()));
72 virtual ~BluetoothProfileServiceProviderImpl() {
73 VLOG(1) << "Cleaning up Bluetooth Profile: " << object_path_.value();
75 // Unregister the object path so we can reuse with a new agent.
76 bus_->UnregisterExportedObject(object_path_);
79 private:
80 // Returns true if the current thread is on the origin thread.
81 bool OnOriginThread() {
82 return base::PlatformThread::CurrentId() == origin_thread_id_;
85 // Called by dbus:: when the profile is unregistered from the Bluetooth
86 // daemon, generally by our request.
87 void Release(dbus::MethodCall* method_call,
88 dbus::ExportedObject::ResponseSender response_sender) {
89 DCHECK(OnOriginThread());
90 DCHECK(delegate_);
92 delegate_->Released();
94 response_sender.Run(dbus::Response::FromMethodCall(method_call));
97 // Called by dbus:: when the Bluetooth daemon establishes a new connection
98 // to the profile.
99 void NewConnection(dbus::MethodCall* method_call,
100 dbus::ExportedObject::ResponseSender response_sender) {
101 DCHECK(OnOriginThread());
102 DCHECK(delegate_);
104 dbus::MessageReader reader(method_call);
105 dbus::ObjectPath device_path;
106 scoped_ptr<dbus::FileDescriptor> fd(new dbus::FileDescriptor());
107 dbus::MessageReader array_reader(NULL);
108 if (!reader.PopObjectPath(&device_path) ||
109 !reader.PopFileDescriptor(fd.get()) ||
110 !reader.PopArray(&array_reader)) {
111 LOG(WARNING) << "NewConnection called with incorrect paramters: "
112 << method_call->ToString();
113 return;
116 Delegate::Options options;
117 while (array_reader.HasMoreData()) {
118 dbus::MessageReader dict_entry_reader(NULL);
119 std::string key;
120 if (!array_reader.PopDictEntry(&dict_entry_reader) ||
121 !dict_entry_reader.PopString(&key)) {
122 LOG(WARNING) << "NewConnection called with incorrect paramters: "
123 << method_call->ToString();
124 } else {
125 if (key == bluetooth_profile::kVersionProperty)
126 dict_entry_reader.PopVariantOfUint16(&options.version);
127 else if (key == bluetooth_profile::kFeaturesProperty)
128 dict_entry_reader.PopVariantOfUint16(&options.features);
132 Delegate::ConfirmationCallback callback = base::Bind(
133 &BluetoothProfileServiceProviderImpl::OnConfirmation,
134 weak_ptr_factory_.GetWeakPtr(),
135 method_call,
136 response_sender);
138 delegate_->NewConnection(device_path, fd.Pass(), options, callback);
141 // Called by dbus:: when the Bluetooth daemon is about to disconnect the
142 // profile.
143 void RequestDisconnection(
144 dbus::MethodCall* method_call,
145 dbus::ExportedObject::ResponseSender response_sender) {
146 DCHECK(OnOriginThread());
147 DCHECK(delegate_);
149 dbus::MessageReader reader(method_call);
150 dbus::ObjectPath device_path;
151 if (!reader.PopObjectPath(&device_path)) {
152 LOG(WARNING) << "RequestDisconnection called with incorrect paramters: "
153 << method_call->ToString();
154 return;
157 Delegate::ConfirmationCallback callback = base::Bind(
158 &BluetoothProfileServiceProviderImpl::OnConfirmation,
159 weak_ptr_factory_.GetWeakPtr(),
160 method_call,
161 response_sender);
163 delegate_->RequestDisconnection(device_path, callback);
166 // Called by dbus:: when the request failed before a reply was returned
167 // from the device.
168 void Cancel(dbus::MethodCall* method_call,
169 dbus::ExportedObject::ResponseSender response_sender) {
170 DCHECK(OnOriginThread());
171 DCHECK(delegate_);
173 delegate_->Cancel();
175 response_sender.Run(dbus::Response::FromMethodCall(method_call));
178 // Called by dbus:: when a method is exported.
179 void OnExported(const std::string& interface_name,
180 const std::string& method_name,
181 bool success) {
182 LOG_IF(WARNING, !success) << "Failed to export "
183 << interface_name << "." << method_name;
186 // Called by the Delegate in response to a method requiring confirmation.
187 void OnConfirmation(dbus::MethodCall* method_call,
188 dbus::ExportedObject::ResponseSender response_sender,
189 Delegate::Status status) {
190 DCHECK(OnOriginThread());
192 switch (status) {
193 case Delegate::SUCCESS: {
194 response_sender.Run(dbus::Response::FromMethodCall(method_call));
195 break;
197 case Delegate::REJECTED: {
198 response_sender.Run(
199 dbus::ErrorResponse::FromMethodCall(
200 method_call, bluetooth_profile::kErrorRejected, "rejected")
201 .PassAs<dbus::Response>());
202 break;
204 case Delegate::CANCELLED: {
205 response_sender.Run(
206 dbus::ErrorResponse::FromMethodCall(
207 method_call, bluetooth_profile::kErrorCanceled, "canceled")
208 .PassAs<dbus::Response>());
209 break;
211 default:
212 NOTREACHED() << "Unexpected status code from delegate: " << status;
216 // Origin thread (i.e. the UI thread in production).
217 base::PlatformThreadId origin_thread_id_;
219 // D-Bus bus object is exported on, not owned by this object and must
220 // outlive it.
221 dbus::Bus* bus_;
223 // All incoming method calls are passed on to the Delegate and a callback
224 // passed to generate the reply. |delegate_| is generally the object that
225 // owns this one, and must outlive it.
226 Delegate* delegate_;
228 // D-Bus object path of object we are exporting, kept so we can unregister
229 // again in our destructor.
230 dbus::ObjectPath object_path_;
232 // D-Bus object we are exporting, owned by this object.
233 scoped_refptr<dbus::ExportedObject> exported_object_;
235 // Weak pointer factory for generating 'this' pointers that might live longer
236 // than we do.
237 // Note: This should remain the last member so it'll be destroyed and
238 // invalidate its weak pointers before any other members are destroyed.
239 base::WeakPtrFactory<BluetoothProfileServiceProviderImpl> weak_ptr_factory_;
241 DISALLOW_COPY_AND_ASSIGN(BluetoothProfileServiceProviderImpl);
244 BluetoothProfileServiceProvider::BluetoothProfileServiceProvider() {
247 BluetoothProfileServiceProvider::~BluetoothProfileServiceProvider() {
250 // static
251 BluetoothProfileServiceProvider* BluetoothProfileServiceProvider::Create(
252 dbus::Bus* bus,
253 const dbus::ObjectPath& object_path,
254 Delegate* delegate) {
255 if (base::SysInfo::IsRunningOnChromeOS()) {
256 return new BluetoothProfileServiceProviderImpl(bus, object_path, delegate);
257 } else {
258 return new FakeBluetoothProfileServiceProvider(object_path, delegate);
262 } // namespace chromeos