| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2012 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 "device/media_transfer_protocol/media_transfer_protocol_daemon_client.h
" | |
| 6 | |
| 7 #include "base/bind.h" | |
| 8 #include "base/memory/weak_ptr.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 "device/media_transfer_protocol/mtp_file_entry.pb.h" | |
| 14 #include "device/media_transfer_protocol/mtp_storage_info.pb.h" | |
| 15 #include "third_party/cros_system_api/dbus/service_constants.h" | |
| 16 | |
| 17 namespace device { | |
| 18 | |
| 19 namespace { | |
| 20 | |
| 21 const char kInvalidResponseMsg[] = "Invalid Response: "; | |
| 22 | |
| 23 // The MediaTransferProtocolDaemonClient implementation. | |
| 24 class MediaTransferProtocolDaemonClientImpl | |
| 25 : public MediaTransferProtocolDaemonClient { | |
| 26 public: | |
| 27 explicit MediaTransferProtocolDaemonClientImpl(dbus::Bus* bus) | |
| 28 : proxy_(bus->GetObjectProxy( | |
| 29 mtpd::kMtpdServiceName, | |
| 30 dbus::ObjectPath(mtpd::kMtpdServicePath))), | |
| 31 weak_ptr_factory_(this) { | |
| 32 } | |
| 33 | |
| 34 // MediaTransferProtocolDaemonClient override. | |
| 35 virtual void EnumerateStorages(const EnumerateStoragesCallback& callback, | |
| 36 const ErrorCallback& error_callback) OVERRIDE { | |
| 37 dbus::MethodCall method_call(mtpd::kMtpdInterface, | |
| 38 mtpd::kEnumerateStorages); | |
| 39 proxy_->CallMethod( | |
| 40 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, | |
| 41 base::Bind(&MediaTransferProtocolDaemonClientImpl::OnEnumerateStorages, | |
| 42 weak_ptr_factory_.GetWeakPtr(), | |
| 43 callback, | |
| 44 error_callback)); | |
| 45 } | |
| 46 | |
| 47 // MediaTransferProtocolDaemonClient override. | |
| 48 virtual void GetStorageInfo(const std::string& storage_name, | |
| 49 const GetStorageInfoCallback& callback, | |
| 50 const ErrorCallback& error_callback) OVERRIDE { | |
| 51 dbus::MethodCall method_call(mtpd::kMtpdInterface, mtpd::kGetStorageInfo); | |
| 52 dbus::MessageWriter writer(&method_call); | |
| 53 writer.AppendString(storage_name); | |
| 54 proxy_->CallMethod( | |
| 55 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, | |
| 56 base::Bind(&MediaTransferProtocolDaemonClientImpl::OnGetStorageInfo, | |
| 57 weak_ptr_factory_.GetWeakPtr(), | |
| 58 storage_name, | |
| 59 callback, | |
| 60 error_callback)); | |
| 61 } | |
| 62 | |
| 63 // MediaTransferProtocolDaemonClient override. | |
| 64 virtual void OpenStorage(const std::string& storage_name, | |
| 65 const std::string& mode, | |
| 66 const OpenStorageCallback& callback, | |
| 67 const ErrorCallback& error_callback) OVERRIDE { | |
| 68 dbus::MethodCall method_call(mtpd::kMtpdInterface, mtpd::kOpenStorage); | |
| 69 dbus::MessageWriter writer(&method_call); | |
| 70 writer.AppendString(storage_name); | |
| 71 DCHECK_EQ(mtpd::kReadOnlyMode, mode); | |
| 72 writer.AppendString(mtpd::kReadOnlyMode); | |
| 73 proxy_->CallMethod( | |
| 74 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, | |
| 75 base::Bind(&MediaTransferProtocolDaemonClientImpl::OnOpenStorage, | |
| 76 weak_ptr_factory_.GetWeakPtr(), | |
| 77 callback, | |
| 78 error_callback)); | |
| 79 } | |
| 80 | |
| 81 // MediaTransferProtocolDaemonClient override. | |
| 82 virtual void CloseStorage(const std::string& handle, | |
| 83 const CloseStorageCallback& callback, | |
| 84 const ErrorCallback& error_callback) OVERRIDE { | |
| 85 dbus::MethodCall method_call(mtpd::kMtpdInterface, mtpd::kCloseStorage); | |
| 86 dbus::MessageWriter writer(&method_call); | |
| 87 writer.AppendString(handle); | |
| 88 proxy_->CallMethod( | |
| 89 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, | |
| 90 base::Bind(&MediaTransferProtocolDaemonClientImpl::OnCloseStorage, | |
| 91 weak_ptr_factory_.GetWeakPtr(), | |
| 92 callback, | |
| 93 error_callback)); | |
| 94 } | |
| 95 | |
| 96 // MediaTransferProtocolDaemonClient override. | |
| 97 virtual void ReadDirectoryByPath( | |
| 98 const std::string& handle, | |
| 99 const std::string& path, | |
| 100 const ReadDirectoryCallback& callback, | |
| 101 const ErrorCallback& error_callback) OVERRIDE { | |
| 102 dbus::MethodCall method_call(mtpd::kMtpdInterface, | |
| 103 mtpd::kReadDirectoryByPath); | |
| 104 dbus::MessageWriter writer(&method_call); | |
| 105 writer.AppendString(handle); | |
| 106 writer.AppendString(path); | |
| 107 proxy_->CallMethod( | |
| 108 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, | |
| 109 base::Bind(&MediaTransferProtocolDaemonClientImpl::OnReadDirectory, | |
| 110 weak_ptr_factory_.GetWeakPtr(), | |
| 111 callback, | |
| 112 error_callback)); | |
| 113 } | |
| 114 | |
| 115 // MediaTransferProtocolDaemonClient override. | |
| 116 virtual void ReadDirectoryById( | |
| 117 const std::string& handle, | |
| 118 uint32 file_id, | |
| 119 const ReadDirectoryCallback& callback, | |
| 120 const ErrorCallback& error_callback) OVERRIDE { | |
| 121 dbus::MethodCall method_call(mtpd::kMtpdInterface, | |
| 122 mtpd::kReadDirectoryById); | |
| 123 dbus::MessageWriter writer(&method_call); | |
| 124 writer.AppendString(handle); | |
| 125 writer.AppendUint32(file_id); | |
| 126 proxy_->CallMethod( | |
| 127 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, | |
| 128 base::Bind(&MediaTransferProtocolDaemonClientImpl::OnReadDirectory, | |
| 129 weak_ptr_factory_.GetWeakPtr(), | |
| 130 callback, | |
| 131 error_callback)); | |
| 132 } | |
| 133 | |
| 134 // MediaTransferProtocolDaemonClient override. | |
| 135 virtual void ReadFileChunkByPath( | |
| 136 const std::string& handle, | |
| 137 const std::string& path, | |
| 138 uint32 offset, | |
| 139 uint32 bytes_to_read, | |
| 140 const ReadFileCallback& callback, | |
| 141 const ErrorCallback& error_callback) OVERRIDE { | |
| 142 dbus::MethodCall method_call(mtpd::kMtpdInterface, | |
| 143 mtpd::kReadFileChunkByPath); | |
| 144 dbus::MessageWriter writer(&method_call); | |
| 145 writer.AppendString(handle); | |
| 146 writer.AppendString(path); | |
| 147 writer.AppendUint32(offset); | |
| 148 writer.AppendUint32(bytes_to_read); | |
| 149 proxy_->CallMethod( | |
| 150 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, | |
| 151 base::Bind(&MediaTransferProtocolDaemonClientImpl::OnReadFile, | |
| 152 weak_ptr_factory_.GetWeakPtr(), | |
| 153 callback, | |
| 154 error_callback)); | |
| 155 } | |
| 156 | |
| 157 // MediaTransferProtocolDaemonClient override. | |
| 158 virtual void ReadFileChunkById(const std::string& handle, | |
| 159 uint32 file_id, | |
| 160 uint32 offset, | |
| 161 uint32 bytes_to_read, | |
| 162 const ReadFileCallback& callback, | |
| 163 const ErrorCallback& error_callback) OVERRIDE { | |
| 164 dbus::MethodCall method_call(mtpd::kMtpdInterface, | |
| 165 mtpd::kReadFileChunkById); | |
| 166 dbus::MessageWriter writer(&method_call); | |
| 167 writer.AppendString(handle); | |
| 168 writer.AppendUint32(file_id); | |
| 169 writer.AppendUint32(offset); | |
| 170 writer.AppendUint32(bytes_to_read); | |
| 171 proxy_->CallMethod( | |
| 172 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, | |
| 173 base::Bind(&MediaTransferProtocolDaemonClientImpl::OnReadFile, | |
| 174 weak_ptr_factory_.GetWeakPtr(), | |
| 175 callback, | |
| 176 error_callback)); | |
| 177 } | |
| 178 | |
| 179 // MediaTransferProtocolDaemonClient override. | |
| 180 virtual void GetFileInfoByPath(const std::string& handle, | |
| 181 const std::string& path, | |
| 182 const GetFileInfoCallback& callback, | |
| 183 const ErrorCallback& error_callback) OVERRIDE { | |
| 184 dbus::MethodCall method_call(mtpd::kMtpdInterface, | |
| 185 mtpd::kGetFileInfoByPath); | |
| 186 dbus::MessageWriter writer(&method_call); | |
| 187 writer.AppendString(handle); | |
| 188 writer.AppendString(path); | |
| 189 proxy_->CallMethod( | |
| 190 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, | |
| 191 base::Bind(&MediaTransferProtocolDaemonClientImpl::OnGetFileInfo, | |
| 192 weak_ptr_factory_.GetWeakPtr(), | |
| 193 callback, | |
| 194 error_callback)); | |
| 195 } | |
| 196 | |
| 197 // MediaTransferProtocolDaemonClient override. | |
| 198 virtual void GetFileInfoById(const std::string& handle, | |
| 199 uint32 file_id, | |
| 200 const GetFileInfoCallback& callback, | |
| 201 const ErrorCallback& error_callback) OVERRIDE { | |
| 202 dbus::MethodCall method_call(mtpd::kMtpdInterface, mtpd::kGetFileInfoById); | |
| 203 dbus::MessageWriter writer(&method_call); | |
| 204 writer.AppendString(handle); | |
| 205 writer.AppendUint32(file_id); | |
| 206 proxy_->CallMethod( | |
| 207 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, | |
| 208 base::Bind(&MediaTransferProtocolDaemonClientImpl::OnGetFileInfo, | |
| 209 weak_ptr_factory_.GetWeakPtr(), | |
| 210 callback, | |
| 211 error_callback)); | |
| 212 } | |
| 213 | |
| 214 // MediaTransferProtocolDaemonClient override. | |
| 215 virtual void SetUpConnections( | |
| 216 const MTPStorageEventHandler& handler) OVERRIDE { | |
| 217 static const SignalEventTuple kSignalEventTuples[] = { | |
| 218 { mtpd::kMTPStorageAttached, true }, | |
| 219 { mtpd::kMTPStorageDetached, false }, | |
| 220 }; | |
| 221 const size_t kNumSignalEventTuples = arraysize(kSignalEventTuples); | |
| 222 | |
| 223 for (size_t i = 0; i < kNumSignalEventTuples; ++i) { | |
| 224 proxy_->ConnectToSignal( | |
| 225 mtpd::kMtpdInterface, | |
| 226 kSignalEventTuples[i].signal_name, | |
| 227 base::Bind(&MediaTransferProtocolDaemonClientImpl::OnMTPStorageSignal, | |
| 228 weak_ptr_factory_.GetWeakPtr(), | |
| 229 handler, | |
| 230 kSignalEventTuples[i].is_attach), | |
| 231 base::Bind(&MediaTransferProtocolDaemonClientImpl::OnSignalConnected, | |
| 232 weak_ptr_factory_.GetWeakPtr())); | |
| 233 } | |
| 234 } | |
| 235 | |
| 236 private: | |
| 237 // A struct to contain a pair of signal name and attachment event type. | |
| 238 // Used by SetUpConnections. | |
| 239 struct SignalEventTuple { | |
| 240 const char *signal_name; | |
| 241 bool is_attach; | |
| 242 }; | |
| 243 | |
| 244 // Handles the result of EnumerateStorages and calls |callback| or | |
| 245 // |error_callback|. | |
| 246 void OnEnumerateStorages(const EnumerateStoragesCallback& callback, | |
| 247 const ErrorCallback& error_callback, | |
| 248 dbus::Response* response) { | |
| 249 if (!response) { | |
| 250 error_callback.Run(); | |
| 251 return; | |
| 252 } | |
| 253 dbus::MessageReader reader(response); | |
| 254 std::vector<std::string> storage_names; | |
| 255 if (!reader.PopArrayOfStrings(&storage_names)) { | |
| 256 LOG(ERROR) << kInvalidResponseMsg << response->ToString(); | |
| 257 error_callback.Run(); | |
| 258 return; | |
| 259 } | |
| 260 callback.Run(storage_names); | |
| 261 } | |
| 262 | |
| 263 // Handles the result of GetStorageInfo and calls |callback| or | |
| 264 // |error_callback|. | |
| 265 void OnGetStorageInfo(const std::string& storage_name, | |
| 266 const GetStorageInfoCallback& callback, | |
| 267 const ErrorCallback& error_callback, | |
| 268 dbus::Response* response) { | |
| 269 if (!response) { | |
| 270 error_callback.Run(); | |
| 271 return; | |
| 272 } | |
| 273 | |
| 274 dbus::MessageReader reader(response); | |
| 275 MtpStorageInfo protobuf; | |
| 276 if (!reader.PopArrayOfBytesAsProto(&protobuf)) { | |
| 277 LOG(ERROR) << kInvalidResponseMsg << response->ToString(); | |
| 278 error_callback.Run(); | |
| 279 return; | |
| 280 } | |
| 281 callback.Run(protobuf); | |
| 282 } | |
| 283 | |
| 284 // Handles the result of OpenStorage and calls |callback| or |error_callback|. | |
| 285 void OnOpenStorage(const OpenStorageCallback& callback, | |
| 286 const ErrorCallback& error_callback, | |
| 287 dbus::Response* response) { | |
| 288 if (!response) { | |
| 289 error_callback.Run(); | |
| 290 return; | |
| 291 } | |
| 292 dbus::MessageReader reader(response); | |
| 293 std::string handle; | |
| 294 if (!reader.PopString(&handle)) { | |
| 295 LOG(ERROR) << kInvalidResponseMsg << response->ToString(); | |
| 296 error_callback.Run(); | |
| 297 return; | |
| 298 } | |
| 299 callback.Run(handle); | |
| 300 } | |
| 301 | |
| 302 // Handles the result of CloseStorage and calls |callback| or | |
| 303 // |error_callback|. | |
| 304 void OnCloseStorage(const CloseStorageCallback& callback, | |
| 305 const ErrorCallback& error_callback, | |
| 306 dbus::Response* response) { | |
| 307 if (!response) { | |
| 308 error_callback.Run(); | |
| 309 return; | |
| 310 } | |
| 311 callback.Run(); | |
| 312 } | |
| 313 | |
| 314 // Handles the result of ReadDirectoryByPath/Id and calls |callback| or | |
| 315 // |error_callback|. | |
| 316 void OnReadDirectory(const ReadDirectoryCallback& callback, | |
| 317 const ErrorCallback& error_callback, | |
| 318 dbus::Response* response) { | |
| 319 if (!response) { | |
| 320 error_callback.Run(); | |
| 321 return; | |
| 322 } | |
| 323 | |
| 324 std::vector<MtpFileEntry> file_entries; | |
| 325 dbus::MessageReader reader(response); | |
| 326 MtpFileEntries entries_protobuf; | |
| 327 if (!reader.PopArrayOfBytesAsProto(&entries_protobuf)) { | |
| 328 LOG(ERROR) << kInvalidResponseMsg << response->ToString(); | |
| 329 error_callback.Run(); | |
| 330 return; | |
| 331 } | |
| 332 | |
| 333 for (int i = 0; i < entries_protobuf.file_entries_size(); ++i) | |
| 334 file_entries.push_back(entries_protobuf.file_entries(i)); | |
| 335 callback.Run(file_entries); | |
| 336 } | |
| 337 | |
| 338 // Handles the result of ReadFileChunkByPath/Id and calls |callback| or | |
| 339 // |error_callback|. | |
| 340 void OnReadFile(const ReadFileCallback& callback, | |
| 341 const ErrorCallback& error_callback, | |
| 342 dbus::Response* response) { | |
| 343 if (!response) { | |
| 344 error_callback.Run(); | |
| 345 return; | |
| 346 } | |
| 347 | |
| 348 uint8* data_bytes = NULL; | |
| 349 size_t data_length = 0; | |
| 350 dbus::MessageReader reader(response); | |
| 351 if (!reader.PopArrayOfBytes(&data_bytes, &data_length)) { | |
| 352 error_callback.Run(); | |
| 353 return; | |
| 354 } | |
| 355 std::string data(reinterpret_cast<const char*>(data_bytes), data_length); | |
| 356 callback.Run(data); | |
| 357 } | |
| 358 | |
| 359 // Handles the result of GetFileInfoByPath/Id and calls |callback| or | |
| 360 // |error_callback|. | |
| 361 void OnGetFileInfo(const GetFileInfoCallback& callback, | |
| 362 const ErrorCallback& error_callback, | |
| 363 dbus::Response* response) { | |
| 364 if (!response) { | |
| 365 error_callback.Run(); | |
| 366 return; | |
| 367 } | |
| 368 | |
| 369 dbus::MessageReader reader(response); | |
| 370 MtpFileEntry protobuf; | |
| 371 if (!reader.PopArrayOfBytesAsProto(&protobuf)) { | |
| 372 LOG(ERROR) << kInvalidResponseMsg << response->ToString(); | |
| 373 error_callback.Run(); | |
| 374 return; | |
| 375 } | |
| 376 callback.Run(protobuf); | |
| 377 } | |
| 378 | |
| 379 // Handles MTPStorageAttached/Dettached signals and calls |handler|. | |
| 380 void OnMTPStorageSignal(MTPStorageEventHandler handler, | |
| 381 bool is_attach, | |
| 382 dbus::Signal* signal) { | |
| 383 dbus::MessageReader reader(signal); | |
| 384 std::string storage_name; | |
| 385 if (!reader.PopString(&storage_name)) { | |
| 386 LOG(ERROR) << "Invalid signal: " << signal->ToString(); | |
| 387 return; | |
| 388 } | |
| 389 DCHECK(!storage_name.empty()); | |
| 390 handler.Run(is_attach, storage_name); | |
| 391 } | |
| 392 | |
| 393 | |
| 394 // Handles the result of signal connection setup. | |
| 395 void OnSignalConnected(const std::string& interface, | |
| 396 const std::string& signal, | |
| 397 bool succeeded) { | |
| 398 LOG_IF(ERROR, !succeeded) << "Connect to " << interface << " " | |
| 399 << signal << " failed."; | |
| 400 } | |
| 401 | |
| 402 dbus::ObjectProxy* proxy_; | |
| 403 | |
| 404 // Note: This should remain the last member so it'll be destroyed and | |
| 405 // invalidate its weak pointers before any other members are destroyed. | |
| 406 base::WeakPtrFactory<MediaTransferProtocolDaemonClientImpl> weak_ptr_factory_; | |
| 407 | |
| 408 DISALLOW_COPY_AND_ASSIGN(MediaTransferProtocolDaemonClientImpl); | |
| 409 }; | |
| 410 | |
| 411 // A stub implementaion of MediaTransferProtocolDaemonClient. | |
| 412 class MediaTransferProtocolDaemonClientStubImpl | |
| 413 : public MediaTransferProtocolDaemonClient { | |
| 414 public: | |
| 415 MediaTransferProtocolDaemonClientStubImpl() {} | |
| 416 virtual ~MediaTransferProtocolDaemonClientStubImpl() {} | |
| 417 | |
| 418 virtual void EnumerateStorages( | |
| 419 const EnumerateStoragesCallback& callback, | |
| 420 const ErrorCallback& error_callback) OVERRIDE {} | |
| 421 virtual void GetStorageInfo( | |
| 422 const std::string& storage_name, | |
| 423 const GetStorageInfoCallback& callback, | |
| 424 const ErrorCallback& error_callback) OVERRIDE {} | |
| 425 virtual void OpenStorage(const std::string& storage_name, | |
| 426 const std::string& mode, | |
| 427 const OpenStorageCallback& callback, | |
| 428 const ErrorCallback& error_callback) OVERRIDE {} | |
| 429 virtual void CloseStorage(const std::string& handle, | |
| 430 const CloseStorageCallback& callback, | |
| 431 const ErrorCallback& error_callback) OVERRIDE {} | |
| 432 virtual void ReadDirectoryByPath( | |
| 433 const std::string& handle, | |
| 434 const std::string& path, | |
| 435 const ReadDirectoryCallback& callback, | |
| 436 const ErrorCallback& error_callback) OVERRIDE {} | |
| 437 virtual void ReadDirectoryById( | |
| 438 const std::string& handle, | |
| 439 uint32 file_id, | |
| 440 const ReadDirectoryCallback& callback, | |
| 441 const ErrorCallback& error_callback) OVERRIDE {} | |
| 442 virtual void ReadFileChunkByPath( | |
| 443 const std::string& handle, | |
| 444 const std::string& path, | |
| 445 uint32 offset, | |
| 446 uint32 length, | |
| 447 const ReadFileCallback& callback, | |
| 448 const ErrorCallback& error_callback) OVERRIDE {} | |
| 449 virtual void ReadFileChunkById( | |
| 450 const std::string& handle, | |
| 451 uint32 file_id, | |
| 452 uint32 offset, | |
| 453 uint32 length, | |
| 454 const ReadFileCallback& callback, | |
| 455 const ErrorCallback& error_callback) OVERRIDE {} | |
| 456 virtual void GetFileInfoByPath( | |
| 457 const std::string& handle, | |
| 458 const std::string& path, | |
| 459 const GetFileInfoCallback& callback, | |
| 460 const ErrorCallback& error_callback) OVERRIDE {} | |
| 461 virtual void GetFileInfoById(const std::string& handle, | |
| 462 uint32 file_id, | |
| 463 const GetFileInfoCallback& callback, | |
| 464 const ErrorCallback& error_callback) OVERRIDE {} | |
| 465 virtual void SetUpConnections( | |
| 466 const MTPStorageEventHandler& handler) OVERRIDE {} | |
| 467 | |
| 468 private: | |
| 469 DISALLOW_COPY_AND_ASSIGN(MediaTransferProtocolDaemonClientStubImpl); | |
| 470 }; | |
| 471 | |
| 472 } // namespace | |
| 473 | |
| 474 //////////////////////////////////////////////////////////////////////////////// | |
| 475 // MediaTransferProtocolDaemonClient | |
| 476 | |
| 477 MediaTransferProtocolDaemonClient::MediaTransferProtocolDaemonClient() {} | |
| 478 | |
| 479 MediaTransferProtocolDaemonClient::~MediaTransferProtocolDaemonClient() {} | |
| 480 | |
| 481 // static | |
| 482 MediaTransferProtocolDaemonClient* | |
| 483 MediaTransferProtocolDaemonClient::Create(dbus::Bus* bus, bool is_stub) { | |
| 484 if (is_stub) | |
| 485 return new MediaTransferProtocolDaemonClientStubImpl(); | |
| 486 return new MediaTransferProtocolDaemonClientImpl(bus); | |
| 487 } | |
| 488 | |
| 489 } // namespace device | |
| OLD | NEW |