diff options
author | keybuk@chromium.org <keybuk@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-06-12 14:47:32 +0000 |
---|---|---|
committer | keybuk@chromium.org <keybuk@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-06-12 14:47:32 +0000 |
commit | 627f4f4ec29191d02998358a0b9d8896547ffca1 (patch) | |
tree | dba063c373e62ef6dca9cd8dd0fc05150aa8efd4 /chromeos/dbus/bluetooth_agent_service_provider.cc | |
parent | 5ddc6f5f34fc08363a5acbdd089a1d8be680e8fb (diff) | |
download | chromium_src-627f4f4ec29191d02998358a0b9d8896547ffca1.zip chromium_src-627f4f4ec29191d02998358a0b9d8896547ffca1.tar.gz chromium_src-627f4f4ec29191d02998358a0b9d8896547ffca1.tar.bz2 |
Bluetooth: drop "Experimental" from Chrome OS backend
BUG=221813
TEST=device_unittests
Review URL: https://chromiumcodereview.appspot.com/14932007
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@205777 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chromeos/dbus/bluetooth_agent_service_provider.cc')
-rw-r--r-- | chromeos/dbus/bluetooth_agent_service_provider.cc | 479 |
1 files changed, 479 insertions, 0 deletions
diff --git a/chromeos/dbus/bluetooth_agent_service_provider.cc b/chromeos/dbus/bluetooth_agent_service_provider.cc new file mode 100644 index 0000000..ece8096 --- /dev/null +++ b/chromeos/dbus/bluetooth_agent_service_provider.cc @@ -0,0 +1,479 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chromeos/dbus/bluetooth_agent_service_provider.h" + +#include <string> + +#include "base/bind.h" +#include "base/chromeos/chromeos_version.h" +#include "base/logging.h" +#include "base/memory/ref_counted.h" +#include "base/threading/platform_thread.h" +#include "chromeos/dbus/fake_bluetooth_agent_service_provider.h" +#include "dbus/bus.h" +#include "dbus/exported_object.h" +#include "dbus/message.h" +#include "dbus/object_path.h" +#include "third_party/cros_system_api/dbus/service_constants.h" + +namespace chromeos { + +// The BluetoothAgentServiceProvider implementation used in production. +class BluetoothAgentServiceProviderImpl + : public BluetoothAgentServiceProvider { + public: + BluetoothAgentServiceProviderImpl(dbus::Bus* bus, + const dbus::ObjectPath& object_path, + Delegate* delegate) + : origin_thread_id_(base::PlatformThread::CurrentId()), + bus_(bus), + delegate_(delegate), + object_path_(object_path), + weak_ptr_factory_(this) { + VLOG(1) << "Creating Bluetooth Agent: " << object_path_.value(); + + exported_object_ = bus_->GetExportedObject(object_path_); + + exported_object_->ExportMethod( + bluetooth_agent::kBluetoothAgentInterface, + bluetooth_agent::kRelease, + base::Bind(&BluetoothAgentServiceProviderImpl::Release, + weak_ptr_factory_.GetWeakPtr()), + base::Bind(&BluetoothAgentServiceProviderImpl::OnExported, + weak_ptr_factory_.GetWeakPtr())); + + exported_object_->ExportMethod( + bluetooth_agent::kBluetoothAgentInterface, + bluetooth_agent::kRequestPinCode, + base::Bind(&BluetoothAgentServiceProviderImpl::RequestPinCode, + weak_ptr_factory_.GetWeakPtr()), + base::Bind(&BluetoothAgentServiceProviderImpl::OnExported, + weak_ptr_factory_.GetWeakPtr())); + + exported_object_->ExportMethod( + bluetooth_agent::kBluetoothAgentInterface, + bluetooth_agent::kDisplayPinCode, + base::Bind(&BluetoothAgentServiceProviderImpl::DisplayPinCode, + weak_ptr_factory_.GetWeakPtr()), + base::Bind(&BluetoothAgentServiceProviderImpl::OnExported, + weak_ptr_factory_.GetWeakPtr())); + + exported_object_->ExportMethod( + bluetooth_agent::kBluetoothAgentInterface, + bluetooth_agent::kRequestPasskey, + base::Bind(&BluetoothAgentServiceProviderImpl::RequestPasskey, + weak_ptr_factory_.GetWeakPtr()), + base::Bind(&BluetoothAgentServiceProviderImpl::OnExported, + weak_ptr_factory_.GetWeakPtr())); + + exported_object_->ExportMethod( + bluetooth_agent::kBluetoothAgentInterface, + bluetooth_agent::kDisplayPasskey, + base::Bind(&BluetoothAgentServiceProviderImpl::DisplayPasskey, + weak_ptr_factory_.GetWeakPtr()), + base::Bind(&BluetoothAgentServiceProviderImpl::OnExported, + weak_ptr_factory_.GetWeakPtr())); + + exported_object_->ExportMethod( + bluetooth_agent::kBluetoothAgentInterface, + bluetooth_agent::kRequestConfirmation, + base::Bind(&BluetoothAgentServiceProviderImpl::RequestConfirmation, + weak_ptr_factory_.GetWeakPtr()), + base::Bind(&BluetoothAgentServiceProviderImpl::OnExported, + weak_ptr_factory_.GetWeakPtr())); + + exported_object_->ExportMethod( + bluetooth_agent::kBluetoothAgentInterface, + bluetooth_agent::kRequestAuthorization, + base::Bind(&BluetoothAgentServiceProviderImpl::RequestAuthorization, + weak_ptr_factory_.GetWeakPtr()), + base::Bind(&BluetoothAgentServiceProviderImpl::OnExported, + weak_ptr_factory_.GetWeakPtr())); + + exported_object_->ExportMethod( + bluetooth_agent::kBluetoothAgentInterface, + bluetooth_agent::kAuthorizeService, + base::Bind(&BluetoothAgentServiceProviderImpl::AuthorizeService, + weak_ptr_factory_.GetWeakPtr()), + base::Bind(&BluetoothAgentServiceProviderImpl::OnExported, + weak_ptr_factory_.GetWeakPtr())); + + exported_object_->ExportMethod( + bluetooth_agent::kBluetoothAgentInterface, + bluetooth_agent::kCancel, + base::Bind(&BluetoothAgentServiceProviderImpl::Cancel, + weak_ptr_factory_.GetWeakPtr()), + base::Bind(&BluetoothAgentServiceProviderImpl::OnExported, + weak_ptr_factory_.GetWeakPtr())); + } + + virtual ~BluetoothAgentServiceProviderImpl() { + VLOG(1) << "Cleaning up Bluetooth Agent: " << object_path_.value(); + + // Unregister the object path so we can reuse with a new agent. + bus_->UnregisterExportedObject(object_path_); + } + + private: + // Returns true if the current thread is on the origin thread. + bool OnOriginThread() { + return base::PlatformThread::CurrentId() == origin_thread_id_; + } + + // Called by dbus:: when the agent is unregistered from the Bluetooth + // daemon, generally at the end of a pairing request. + void Release(dbus::MethodCall* method_call, + dbus::ExportedObject::ResponseSender response_sender) { + DCHECK(OnOriginThread()); + DCHECK(delegate_); + + delegate_->Release(); + + response_sender.Run(dbus::Response::FromMethodCall(method_call)); + } + + // Called by dbus:: when the Bluetooth daemon requires a PIN Code for + // device authentication. + void RequestPinCode(dbus::MethodCall* method_call, + dbus::ExportedObject::ResponseSender response_sender) { + DCHECK(OnOriginThread()); + DCHECK(delegate_); + + dbus::MessageReader reader(method_call); + dbus::ObjectPath device_path; + if (!reader.PopObjectPath(&device_path)) { + LOG(WARNING) << "RequestPinCode called with incorrect paramters: " + << method_call->ToString(); + return; + } + + Delegate::PinCodeCallback callback = base::Bind( + &BluetoothAgentServiceProviderImpl::OnPinCode, + weak_ptr_factory_.GetWeakPtr(), + method_call, + response_sender); + + delegate_->RequestPinCode(device_path, callback); + } + + // Called by dbus:: when the Bluetooth daemon requires that the user + // enter a PIN Code into the remote device so that it may be + // authenticated. + void DisplayPinCode(dbus::MethodCall* method_call, + dbus::ExportedObject::ResponseSender response_sender) { + DCHECK(OnOriginThread()); + DCHECK(delegate_); + + dbus::MessageReader reader(method_call); + dbus::ObjectPath device_path; + std::string pincode; + if (!reader.PopObjectPath(&device_path) || + !reader.PopString(&pincode)) { + LOG(WARNING) << "DisplayPinCode called with incorrect paramters: " + << method_call->ToString(); + return; + } + + delegate_->DisplayPinCode(device_path, pincode); + + response_sender.Run(dbus::Response::FromMethodCall(method_call)); + } + + // Called by dbus:: when the Bluetooth daemon requires a Passkey for + // device authentication. + void RequestPasskey(dbus::MethodCall* method_call, + dbus::ExportedObject::ResponseSender response_sender) { + DCHECK(OnOriginThread()); + DCHECK(delegate_); + + dbus::MessageReader reader(method_call); + dbus::ObjectPath device_path; + if (!reader.PopObjectPath(&device_path)) { + LOG(WARNING) << "RequestPasskey called with incorrect paramters: " + << method_call->ToString(); + return; + } + + Delegate::PasskeyCallback callback = base::Bind( + &BluetoothAgentServiceProviderImpl::OnPasskey, + weak_ptr_factory_.GetWeakPtr(), + method_call, + response_sender); + + delegate_->RequestPasskey(device_path, callback); + } + + // Called by dbus:: when the Bluetooth daemon requires that the user + // enter a Passkey into the remote device so that it may be + // authenticated. + void DisplayPasskey(dbus::MethodCall* method_call, + dbus::ExportedObject::ResponseSender response_sender) { + DCHECK(OnOriginThread()); + DCHECK(delegate_); + + dbus::MessageReader reader(method_call); + dbus::ObjectPath device_path; + uint32 passkey; + uint16 entered; + if (!reader.PopObjectPath(&device_path) || + !reader.PopUint32(&passkey) || + !reader.PopUint16(&entered)) { + LOG(WARNING) << "DisplayPasskey called with incorrect paramters: " + << method_call->ToString(); + return; + } + + delegate_->DisplayPasskey(device_path, passkey, entered); + + response_sender.Run(dbus::Response::FromMethodCall(method_call)); + } + + // Called by dbus:: when the Bluetooth daemon requires that the user + // confirm that a Passkey is displayed on the screen of the remote + // device so that it may be authenticated. + void RequestConfirmation( + dbus::MethodCall* method_call, + dbus::ExportedObject::ResponseSender response_sender) { + DCHECK(OnOriginThread()); + DCHECK(delegate_); + + dbus::MessageReader reader(method_call); + dbus::ObjectPath device_path; + uint32 passkey; + if (!reader.PopObjectPath(&device_path) || + !reader.PopUint32(&passkey)) { + LOG(WARNING) << "RequestConfirmation called with incorrect paramters: " + << method_call->ToString(); + return; + } + + Delegate::ConfirmationCallback callback = base::Bind( + &BluetoothAgentServiceProviderImpl::OnConfirmation, + weak_ptr_factory_.GetWeakPtr(), + method_call, + response_sender); + + delegate_->RequestConfirmation(device_path, passkey, callback); + } + + // Called by dbus:: when the Bluetooth daemon requires that the user + // confirm an incoming just-works pairing. + void RequestAuthorization( + dbus::MethodCall* method_call, + dbus::ExportedObject::ResponseSender response_sender) { + DCHECK(OnOriginThread()); + DCHECK(delegate_); + + dbus::MessageReader reader(method_call); + dbus::ObjectPath device_path; + if (!reader.PopObjectPath(&device_path)) { + LOG(WARNING) << "RequestAuthorization called with incorrect paramters: " + << method_call->ToString(); + return; + } + + Delegate::ConfirmationCallback callback = base::Bind( + &BluetoothAgentServiceProviderImpl::OnConfirmation, + weak_ptr_factory_.GetWeakPtr(), + method_call, + response_sender); + + delegate_->RequestAuthorization(device_path, callback); + } + + // Called by dbus:: when the Bluetooth daemon requires that the user + // confirm that that a remote device is authorized to connect to a service + // UUID. + void AuthorizeService(dbus::MethodCall* method_call, + dbus::ExportedObject::ResponseSender response_sender) { + DCHECK(OnOriginThread()); + DCHECK(delegate_); + + dbus::MessageReader reader(method_call); + dbus::ObjectPath device_path; + std::string uuid; + if (!reader.PopObjectPath(&device_path) || + !reader.PopString(&uuid)) { + LOG(WARNING) << "AuthorizeService called with incorrect paramters: " + << method_call->ToString(); + return; + } + + Delegate::ConfirmationCallback callback = base::Bind( + &BluetoothAgentServiceProviderImpl::OnConfirmation, + weak_ptr_factory_.GetWeakPtr(), + method_call, + response_sender); + + delegate_->AuthorizeService(device_path, uuid, callback); + } + + // Called by dbus:: when the request failed before a reply was returned + // from the device. + void Cancel(dbus::MethodCall* method_call, + dbus::ExportedObject::ResponseSender response_sender) { + DCHECK(OnOriginThread()); + DCHECK(delegate_); + + delegate_->Cancel(); + + response_sender.Run(dbus::Response::FromMethodCall(method_call)); + } + + // Called by dbus:: when a method is exported. + void OnExported(const std::string& interface_name, + const std::string& method_name, + bool success) { + LOG_IF(WARNING, !success) << "Failed to export " + << interface_name << "." << method_name; + } + + // Called by the Delegate to response to a method requesting a PIN code. + void OnPinCode(dbus::MethodCall* method_call, + dbus::ExportedObject::ResponseSender response_sender, + Delegate::Status status, + const std::string& pincode) { + DCHECK(OnOriginThread()); + + switch (status) { + case Delegate::SUCCESS: { + scoped_ptr<dbus::Response> response( + dbus::Response::FromMethodCall(method_call)); + dbus::MessageWriter writer(response.get()); + writer.AppendString(pincode); + response_sender.Run(response.Pass()); + break; + } + case Delegate::REJECTED: { + response_sender.Run( + dbus::ErrorResponse::FromMethodCall( + method_call, bluetooth_agent::kErrorRejected, "rejected") + .PassAs<dbus::Response>()); + break; + } + case Delegate::CANCELLED: { + response_sender.Run( + dbus::ErrorResponse::FromMethodCall( + method_call, bluetooth_agent::kErrorCanceled, "canceled") + .PassAs<dbus::Response>()); + break; + } + default: + NOTREACHED() << "Unexpected status code from delegate: " << status; + } + } + + // Called by the Delegate to response to a method requesting a Passkey. + void OnPasskey(dbus::MethodCall* method_call, + dbus::ExportedObject::ResponseSender response_sender, + Delegate::Status status, + uint32 passkey) { + DCHECK(OnOriginThread()); + + switch (status) { + case Delegate::SUCCESS: { + scoped_ptr<dbus::Response> response( + dbus::Response::FromMethodCall(method_call)); + dbus::MessageWriter writer(response.get()); + writer.AppendUint32(passkey); + response_sender.Run(response.Pass()); + break; + } + case Delegate::REJECTED: { + response_sender.Run( + dbus::ErrorResponse::FromMethodCall( + method_call, bluetooth_agent::kErrorRejected, "rejected") + .PassAs<dbus::Response>()); + break; + } + case Delegate::CANCELLED: { + response_sender.Run( + dbus::ErrorResponse::FromMethodCall( + method_call, bluetooth_agent::kErrorCanceled, "canceled") + .PassAs<dbus::Response>()); + break; + } + default: + NOTREACHED() << "Unexpected status code from delegate: " << status; + } + } + + // Called by the Delegate in response to a method requiring confirmation. + void OnConfirmation(dbus::MethodCall* method_call, + dbus::ExportedObject::ResponseSender response_sender, + Delegate::Status status) { + DCHECK(OnOriginThread()); + + switch (status) { + case Delegate::SUCCESS: { + response_sender.Run(dbus::Response::FromMethodCall(method_call)); + break; + } + case Delegate::REJECTED: { + response_sender.Run( + dbus::ErrorResponse::FromMethodCall( + method_call, bluetooth_agent::kErrorRejected, "rejected") + .PassAs<dbus::Response>()); + break; + } + case Delegate::CANCELLED: { + response_sender.Run( + dbus::ErrorResponse::FromMethodCall( + method_call, bluetooth_agent::kErrorCanceled, "canceled") + .PassAs<dbus::Response>()); + break; + } + default: + NOTREACHED() << "Unexpected status code from delegate: " << status; + } + } + + // Origin thread (i.e. the UI thread in production). + base::PlatformThreadId origin_thread_id_; + + // D-Bus bus object is exported on, not owned by this object and must + // outlive it. + dbus::Bus* bus_; + + // All incoming method calls are passed on to the Delegate and a callback + // passed to generate the reply. |delegate_| is generally the object that + // owns this one, and must outlive it. + Delegate* delegate_; + + // D-Bus object path of object we are exporting, kept so we can unregister + // again in our destructor. + dbus::ObjectPath object_path_; + + // D-Bus object we are exporting, owned by this object. + scoped_refptr<dbus::ExportedObject> exported_object_; + + // Weak pointer factory for generating 'this' pointers that might live longer + // than we do. + // Note: This should remain the last member so it'll be destroyed and + // invalidate its weak pointers before any other members are destroyed. + base::WeakPtrFactory<BluetoothAgentServiceProviderImpl> weak_ptr_factory_; + + DISALLOW_COPY_AND_ASSIGN(BluetoothAgentServiceProviderImpl); +}; + +BluetoothAgentServiceProvider::BluetoothAgentServiceProvider() { +} + +BluetoothAgentServiceProvider::~BluetoothAgentServiceProvider() { +} + +// static +BluetoothAgentServiceProvider* BluetoothAgentServiceProvider::Create( + dbus::Bus* bus, + const dbus::ObjectPath& object_path, + Delegate* delegate) { + if (base::chromeos::IsRunningOnChromeOS()) { + return new BluetoothAgentServiceProviderImpl(bus, object_path, delegate); + } else { + return new FakeBluetoothAgentServiceProvider(object_path, delegate); + } +} + +} // namespace chromeos |