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