Home | History | Annotate | Download | only in dbus
      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.
      4 
      5 #include "chromeos/dbus/bluetooth_profile_manager_client.h"
      6 
      7 #include "base/bind.h"
      8 #include "base/logging.h"
      9 #include "dbus/bus.h"
     10 #include "dbus/message.h"
     11 #include "dbus/object_path.h"
     12 #include "dbus/object_proxy.h"
     13 #include "third_party/cros_system_api/dbus/service_constants.h"
     14 
     15 namespace chromeos {
     16 
     17 const char BluetoothProfileManagerClient::kNoResponseError[] =
     18     "org.chromium.Error.NoResponse";
     19 
     20 
     21 BluetoothProfileManagerClient::Options::Options() {
     22 }
     23 
     24 BluetoothProfileManagerClient::Options::~Options() {
     25 }
     26 
     27 // The BluetoothProfileManagerClient implementation used in production.
     28 class BluetoothProfileManagerClientImpl
     29     : public BluetoothProfileManagerClient {
     30  public:
     31   BluetoothProfileManagerClientImpl() : weak_ptr_factory_(this) {}
     32 
     33   virtual ~BluetoothProfileManagerClientImpl() {
     34   }
     35 
     36   // BluetoothProfileManagerClient override.
     37   virtual void RegisterProfile(const dbus::ObjectPath& profile_path,
     38                                const std::string& uuid,
     39                                const Options& options,
     40                                const base::Closure& callback,
     41                                const ErrorCallback& error_callback) OVERRIDE {
     42     dbus::MethodCall method_call(
     43     bluetooth_profile_manager::kBluetoothProfileManagerInterface,
     44     bluetooth_profile_manager::kRegisterProfile);
     45 
     46     dbus::MessageWriter writer(&method_call);
     47     writer.AppendObjectPath(profile_path);
     48     writer.AppendString(uuid);
     49 
     50     dbus::MessageWriter array_writer(NULL);
     51     writer.OpenArray("{sv}", &array_writer);
     52 
     53     dbus::MessageWriter dict_writer(NULL);
     54 
     55     // Send Name if provided.
     56     if (options.name.get() != NULL) {
     57       array_writer.OpenDictEntry(&dict_writer);
     58       dict_writer.AppendString(bluetooth_profile_manager::kNameOption);
     59       dict_writer.AppendVariantOfString(*(options.name));
     60       array_writer.CloseContainer(&dict_writer);
     61     }
     62 
     63     // Send Service if provided.
     64     if (options.service.get() != NULL) {
     65       dbus::MessageWriter dict_writer(NULL);
     66       array_writer.OpenDictEntry(&dict_writer);
     67       dict_writer.AppendString(bluetooth_profile_manager::kServiceOption);
     68       dict_writer.AppendVariantOfString(*(options.service));
     69       array_writer.CloseContainer(&dict_writer);
     70     }
     71 
     72     // Send Role if not the default value.
     73     if (options.role != SYMMETRIC) {
     74       dbus::MessageWriter dict_writer(NULL);
     75       array_writer.OpenDictEntry(&dict_writer);
     76       dict_writer.AppendString(bluetooth_profile_manager::kRoleOption);
     77       if (options.role == CLIENT)
     78         dict_writer.AppendVariantOfString(
     79             bluetooth_profile_manager::kClientRoleOption);
     80       else if (options.role == SERVER)
     81         dict_writer.AppendVariantOfString(
     82             bluetooth_profile_manager::kServerRoleOption);
     83       else
     84         dict_writer.AppendVariantOfString("");
     85       array_writer.CloseContainer(&dict_writer);
     86     }
     87 
     88     // Send Channel if provided.
     89     if (options.channel.get() != NULL) {
     90       dbus::MessageWriter dict_writer(NULL);
     91       array_writer.OpenDictEntry(&dict_writer);
     92       dict_writer.AppendString(bluetooth_profile_manager::kChannelOption);
     93       dict_writer.AppendVariantOfUint16(*(options.channel));
     94       array_writer.CloseContainer(&dict_writer);
     95     }
     96 
     97     // Send PSM if provided.
     98     if (options.psm.get() != NULL) {
     99       dbus::MessageWriter dict_writer(NULL);
    100       array_writer.OpenDictEntry(&dict_writer);
    101       dict_writer.AppendString(bluetooth_profile_manager::kPSMOption);
    102       dict_writer.AppendVariantOfUint16(*(options.psm));
    103       array_writer.CloseContainer(&dict_writer);
    104     }
    105 
    106     // Send RequireAuthentication if provided.
    107     if (options.require_authentication.get() != NULL) {
    108       array_writer.OpenDictEntry(&dict_writer);
    109       dict_writer.AppendString(
    110           bluetooth_profile_manager::kRequireAuthenticationOption);
    111       dict_writer.AppendVariantOfBool(*(options.require_authentication));
    112       array_writer.CloseContainer(&dict_writer);
    113     }
    114 
    115     // Send RequireAuthorization if provided.
    116     if (options.require_authorization.get() != NULL) {
    117       array_writer.OpenDictEntry(&dict_writer);
    118       dict_writer.AppendString(
    119           bluetooth_profile_manager::kRequireAuthorizationOption);
    120       dict_writer.AppendVariantOfBool(*(options.require_authorization));
    121       array_writer.CloseContainer(&dict_writer);
    122     }
    123 
    124     // Send AutoConnect if provided.
    125     if (options.auto_connect.get() != NULL) {
    126       array_writer.OpenDictEntry(&dict_writer);
    127       dict_writer.AppendString(
    128           bluetooth_profile_manager::kAutoConnectOption);
    129       dict_writer.AppendVariantOfBool(*(options.auto_connect));
    130       array_writer.CloseContainer(&dict_writer);
    131     }
    132 
    133     // Send ServiceRecord if provided.
    134     if (options.service_record.get() != NULL) {
    135       dbus::MessageWriter dict_writer(NULL);
    136       array_writer.OpenDictEntry(&dict_writer);
    137       dict_writer.AppendString(bluetooth_profile_manager::kServiceRecordOption);
    138       dict_writer.AppendVariantOfString(*(options.service_record));
    139       array_writer.CloseContainer(&dict_writer);
    140     }
    141 
    142     // Send Version if provided.
    143     if (options.version.get() != NULL) {
    144       dbus::MessageWriter dict_writer(NULL);
    145       array_writer.OpenDictEntry(&dict_writer);
    146       dict_writer.AppendString(bluetooth_profile_manager::kVersionOption);
    147       dict_writer.AppendVariantOfUint16(*(options.version));
    148       array_writer.CloseContainer(&dict_writer);
    149     }
    150 
    151     // Send Features if provided.
    152     if (options.features.get() != NULL) {
    153       dbus::MessageWriter dict_writer(NULL);
    154       array_writer.OpenDictEntry(&dict_writer);
    155       dict_writer.AppendString(bluetooth_profile_manager::kFeaturesOption);
    156       dict_writer.AppendVariantOfUint16(*(options.features));
    157       array_writer.CloseContainer(&dict_writer);
    158     }
    159 
    160     writer.CloseContainer(&array_writer);
    161 
    162     object_proxy_->CallMethodWithErrorCallback(
    163         &method_call,
    164         dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
    165         base::Bind(&BluetoothProfileManagerClientImpl::OnSuccess,
    166                    weak_ptr_factory_.GetWeakPtr(), callback),
    167         base::Bind(&BluetoothProfileManagerClientImpl::OnError,
    168                    weak_ptr_factory_.GetWeakPtr(), error_callback));
    169   }
    170 
    171   // BluetoothProfileManagerClient override.
    172   virtual void UnregisterProfile(const dbus::ObjectPath& profile_path,
    173                                  const base::Closure& callback,
    174                                  const ErrorCallback& error_callback) OVERRIDE {
    175     dbus::MethodCall method_call(
    176       bluetooth_profile_manager::kBluetoothProfileManagerInterface,
    177       bluetooth_profile_manager::kUnregisterProfile);
    178 
    179     dbus::MessageWriter writer(&method_call);
    180     writer.AppendObjectPath(profile_path);
    181 
    182     object_proxy_->CallMethodWithErrorCallback(
    183         &method_call,
    184         dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
    185         base::Bind(&BluetoothProfileManagerClientImpl::OnSuccess,
    186                    weak_ptr_factory_.GetWeakPtr(), callback),
    187         base::Bind(&BluetoothProfileManagerClientImpl::OnError,
    188                    weak_ptr_factory_.GetWeakPtr(), error_callback));
    189   }
    190 
    191  protected:
    192   virtual void Init(dbus::Bus* bus) OVERRIDE {
    193     DCHECK(bus);
    194     object_proxy_ = bus->GetObjectProxy(
    195         bluetooth_profile_manager::kBluetoothProfileManagerServiceName,
    196         dbus::ObjectPath(
    197             bluetooth_profile_manager::kBluetoothProfileManagerServicePath));
    198   }
    199 
    200  private:
    201   // Called when a response for successful method call is received.
    202   void OnSuccess(const base::Closure& callback,
    203                  dbus::Response* response) {
    204     DCHECK(response);
    205     callback.Run();
    206   }
    207 
    208   // Called when a response for a failed method call is received.
    209   void OnError(const ErrorCallback& error_callback,
    210                dbus::ErrorResponse* response) {
    211     // Error response has optional error message argument.
    212     std::string error_name;
    213     std::string error_message;
    214     if (response) {
    215       dbus::MessageReader reader(response);
    216       error_name = response->GetErrorName();
    217       reader.PopString(&error_message);
    218     } else {
    219       error_name = kNoResponseError;
    220       error_message = "";
    221     }
    222     error_callback.Run(error_name, error_message);
    223   }
    224 
    225   dbus::ObjectProxy* object_proxy_;
    226 
    227   // Weak pointer factory for generating 'this' pointers that might live longer
    228   // than we do.
    229   // Note: This should remain the last member so it'll be destroyed and
    230   // invalidate its weak pointers before any other members are destroyed.
    231   base::WeakPtrFactory<BluetoothProfileManagerClientImpl> weak_ptr_factory_;
    232 
    233   DISALLOW_COPY_AND_ASSIGN(BluetoothProfileManagerClientImpl);
    234 };
    235 
    236 BluetoothProfileManagerClient::BluetoothProfileManagerClient() {
    237 }
    238 
    239 BluetoothProfileManagerClient::~BluetoothProfileManagerClient() {
    240 }
    241 
    242 BluetoothProfileManagerClient* BluetoothProfileManagerClient::Create() {
    243   return new BluetoothProfileManagerClientImpl();
    244 }
    245 
    246 }  // namespace chromeos
    247