Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "device/media_transfer_protocol/media_transfer_protocol_manager.h" | 5 #include "device/media_transfer_protocol/media_transfer_protocol_manager.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <map> | 8 #include <map> |
| 9 #include <queue> | 9 #include <queue> |
| 10 #include <set> | 10 #include <set> |
| (...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 154 mtp_client_->CloseStorage( | 154 mtp_client_->CloseStorage( |
| 155 storage_handle, | 155 storage_handle, |
| 156 base::Bind(&MediaTransferProtocolManagerImpl::OnCloseStorage, | 156 base::Bind(&MediaTransferProtocolManagerImpl::OnCloseStorage, |
| 157 weak_ptr_factory_.GetWeakPtr()), | 157 weak_ptr_factory_.GetWeakPtr()), |
| 158 base::Bind(&MediaTransferProtocolManagerImpl::OnCloseStorageError, | 158 base::Bind(&MediaTransferProtocolManagerImpl::OnCloseStorageError, |
| 159 weak_ptr_factory_.GetWeakPtr())); | 159 weak_ptr_factory_.GetWeakPtr())); |
| 160 } | 160 } |
| 161 | 161 |
| 162 // MediaTransferProtocolManager override. | 162 // MediaTransferProtocolManager override. |
| 163 void ReadDirectory(const std::string& storage_handle, | 163 void ReadDirectory(const std::string& storage_handle, |
| 164 uint32 file_id, | 164 const uint32 file_id, |
| 165 const size_t max_size, | |
| 165 const ReadDirectoryCallback& callback) override { | 166 const ReadDirectoryCallback& callback) override { |
| 166 DCHECK(thread_checker_.CalledOnValidThread()); | 167 DCHECK(thread_checker_.CalledOnValidThread()); |
| 167 if (!ContainsKey(handles_, storage_handle) || !mtp_client_) { | 168 if (!ContainsKey(handles_, storage_handle) || !mtp_client_) { |
| 168 callback.Run(std::vector<MtpFileEntry>(), | 169 callback.Run(std::vector<MtpFileEntry>(), |
| 169 false /* no more entries */, | 170 false /* no more entries */, |
| 170 true /* error */); | 171 true /* error */); |
| 171 return; | 172 return; |
| 172 } | 173 } |
| 173 read_directory_callbacks_.push(callback); | 174 read_directory_callbacks_.push(callback); |
| 174 mtp_client_->ReadDirectoryEntryIds( | 175 mtp_client_->ReadDirectoryEntryIds( |
| 175 storage_handle, | 176 storage_handle, file_id, |
| 176 file_id, | 177 base::Bind(&MediaTransferProtocolManagerImpl:: |
| 177 base::Bind(&MediaTransferProtocolManagerImpl::OnReadDirectoryEntryIds, | 178 OnReadDirectoryEntryIdsToReadDirectory, |
| 178 weak_ptr_factory_.GetWeakPtr(), | 179 weak_ptr_factory_.GetWeakPtr(), storage_handle, max_size), |
| 179 storage_handle), | |
| 180 base::Bind(&MediaTransferProtocolManagerImpl::OnReadDirectoryError, | 180 base::Bind(&MediaTransferProtocolManagerImpl::OnReadDirectoryError, |
| 181 weak_ptr_factory_.GetWeakPtr())); | 181 weak_ptr_factory_.GetWeakPtr())); |
| 182 } | 182 } |
| 183 | 183 |
| 184 // MediaTransferProtocolManager override. | 184 // MediaTransferProtocolManager override. |
| 185 void ReadFileChunk(const std::string& storage_handle, | 185 void ReadFileChunk(const std::string& storage_handle, |
| 186 uint32 file_id, | 186 uint32 file_id, |
| 187 uint32 offset, | 187 uint32 offset, |
| 188 uint32 count, | 188 uint32 count, |
| 189 const ReadFileCallback& callback) override { | 189 const ReadFileCallback& callback) override { |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 235 } | 235 } |
| 236 copy_file_from_local_callbacks_.push(callback); | 236 copy_file_from_local_callbacks_.push(callback); |
| 237 mtp_client_->CopyFileFromLocal( | 237 mtp_client_->CopyFileFromLocal( |
| 238 storage_handle, source_file_descriptor, parent_id, file_name, | 238 storage_handle, source_file_descriptor, parent_id, file_name, |
| 239 base::Bind(&MediaTransferProtocolManagerImpl::OnCopyFileFromLocal, | 239 base::Bind(&MediaTransferProtocolManagerImpl::OnCopyFileFromLocal, |
| 240 weak_ptr_factory_.GetWeakPtr()), | 240 weak_ptr_factory_.GetWeakPtr()), |
| 241 base::Bind(&MediaTransferProtocolManagerImpl::OnCopyFileFromLocalError, | 241 base::Bind(&MediaTransferProtocolManagerImpl::OnCopyFileFromLocalError, |
| 242 weak_ptr_factory_.GetWeakPtr())); | 242 weak_ptr_factory_.GetWeakPtr())); |
| 243 } | 243 } |
| 244 | 244 |
| 245 void DeleteObject(const std::string& storage_handle, | |
| 246 const uint32 object_id, | |
| 247 const DeleteObjectCallback& callback) override { | |
| 248 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 249 if (!ContainsKey(handles_, storage_handle) || !mtp_client_) { | |
| 250 callback.Run(true /* error */); | |
| 251 return; | |
| 252 } | |
| 253 delete_object_callbacks_.push(callback); | |
| 254 mtp_client_->DeleteObject( | |
| 255 storage_handle, object_id, | |
| 256 base::Bind(&MediaTransferProtocolManagerImpl::OnDeleteObject, | |
| 257 weak_ptr_factory_.GetWeakPtr()), | |
| 258 base::Bind(&MediaTransferProtocolManagerImpl::OnDeleteObjectError, | |
| 259 weak_ptr_factory_.GetWeakPtr())); | |
| 260 } | |
| 261 | |
| 245 private: | 262 private: |
| 246 // Map of storage names to storage info. | 263 // Map of storage names to storage info. |
| 247 typedef std::map<std::string, MtpStorageInfo> StorageInfoMap; | 264 typedef std::map<std::string, MtpStorageInfo> StorageInfoMap; |
| 248 // Callback queues - DBus communication is in-order, thus callbacks are | 265 // Callback queues - DBus communication is in-order, thus callbacks are |
| 249 // received in the same order as the requests. | 266 // received in the same order as the requests. |
| 250 typedef std::queue<OpenStorageCallback> OpenStorageCallbackQueue; | 267 typedef std::queue<OpenStorageCallback> OpenStorageCallbackQueue; |
| 251 // (callback, handle) | 268 // (callback, handle) |
| 252 typedef std::queue<std::pair<CloseStorageCallback, std::string> | 269 typedef std::queue<std::pair<CloseStorageCallback, std::string> |
| 253 > CloseStorageCallbackQueue; | 270 > CloseStorageCallbackQueue; |
| 254 typedef std::queue<ReadDirectoryCallback> ReadDirectoryCallbackQueue; | 271 typedef std::queue<ReadDirectoryCallback> ReadDirectoryCallbackQueue; |
| 255 typedef std::queue<ReadFileCallback> ReadFileCallbackQueue; | 272 typedef std::queue<ReadFileCallback> ReadFileCallbackQueue; |
| 256 typedef std::queue<GetFileInfoCallback> GetFileInfoCallbackQueue; | 273 typedef std::queue<GetFileInfoCallback> GetFileInfoCallbackQueue; |
| 257 typedef std::queue<CopyFileFromLocalCallback> CopyFileFromLocalCallbackQueue; | 274 typedef std::queue<CopyFileFromLocalCallback> CopyFileFromLocalCallbackQueue; |
| 275 typedef std::queue<DeleteObjectCallback> DeleteObjectCallbackQueue; | |
| 258 | 276 |
| 259 void OnStorageAttached(const std::string& storage_name) { | 277 void OnStorageAttached(const std::string& storage_name) { |
| 260 DCHECK(thread_checker_.CalledOnValidThread()); | 278 DCHECK(thread_checker_.CalledOnValidThread()); |
| 261 mtp_client_->GetStorageInfo( | 279 mtp_client_->GetStorageInfo( |
| 262 storage_name, | 280 storage_name, |
| 263 base::Bind(&MediaTransferProtocolManagerImpl::OnGetStorageInfo, | 281 base::Bind(&MediaTransferProtocolManagerImpl::OnGetStorageInfo, |
| 264 weak_ptr_factory_.GetWeakPtr()), | 282 weak_ptr_factory_.GetWeakPtr()), |
| 265 base::Bind(&base::DoNothing)); | 283 base::Bind(&base::DoNothing)); |
| 266 } | 284 } |
| 267 | 285 |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 350 } | 368 } |
| 351 close_storage_callbacks_.pop(); | 369 close_storage_callbacks_.pop(); |
| 352 } | 370 } |
| 353 | 371 |
| 354 void OnCloseStorageError() { | 372 void OnCloseStorageError() { |
| 355 DCHECK(thread_checker_.CalledOnValidThread()); | 373 DCHECK(thread_checker_.CalledOnValidThread()); |
| 356 close_storage_callbacks_.front().first.Run(true); | 374 close_storage_callbacks_.front().first.Run(true); |
| 357 close_storage_callbacks_.pop(); | 375 close_storage_callbacks_.pop(); |
| 358 } | 376 } |
| 359 | 377 |
| 360 void OnReadDirectoryEntryIds(const std::string& storage_handle, | 378 void OnReadDirectoryEntryIdsToReadDirectory( |
| 361 const std::vector<uint32>& file_ids) { | 379 const std::string& storage_handle, |
| 380 const size_t max_size, | |
| 381 const std::vector<uint32>& file_ids) { | |
| 362 DCHECK(thread_checker_.CalledOnValidThread()); | 382 DCHECK(thread_checker_.CalledOnValidThread()); |
| 363 | 383 |
| 364 if (file_ids.empty()) { | 384 if (file_ids.empty()) { |
| 365 OnGotDirectoryEntries(storage_handle, | 385 OnGotDirectoryEntries(storage_handle, file_ids, kInitialOffset, max_size, |
| 366 file_ids, | 386 file_ids, std::vector<MtpFileEntry>()); |
| 367 kInitialOffset, | |
| 368 file_ids, | |
| 369 std::vector<MtpFileEntry>()); | |
| 370 return; | 387 return; |
| 371 } | 388 } |
| 372 | 389 |
| 373 std::vector<uint32> sorted_file_ids = file_ids; | 390 std::vector<uint32> sorted_file_ids = file_ids; |
| 374 std::sort(sorted_file_ids.begin(), sorted_file_ids.end()); | 391 std::sort(sorted_file_ids.begin(), sorted_file_ids.end()); |
| 375 | 392 |
| 393 const size_t chunk_size = | |
| 394 max_size == 0 ? kFileInfoToFetchChunkSize | |
| 395 : std::min(max_size, kFileInfoToFetchChunkSize); | |
| 396 | |
| 376 mtp_client_->GetFileInfo( | 397 mtp_client_->GetFileInfo( |
| 377 storage_handle, | 398 storage_handle, file_ids, kInitialOffset, chunk_size, |
| 378 file_ids, | |
| 379 kInitialOffset, | |
| 380 kFileInfoToFetchChunkSize, | |
| 381 base::Bind(&MediaTransferProtocolManagerImpl::OnGotDirectoryEntries, | 399 base::Bind(&MediaTransferProtocolManagerImpl::OnGotDirectoryEntries, |
| 382 weak_ptr_factory_.GetWeakPtr(), | 400 weak_ptr_factory_.GetWeakPtr(), storage_handle, file_ids, |
| 383 storage_handle, | 401 kInitialOffset, max_size, sorted_file_ids), |
| 384 file_ids, | |
| 385 kInitialOffset, | |
| 386 sorted_file_ids), | |
| 387 base::Bind(&MediaTransferProtocolManagerImpl::OnReadDirectoryError, | 402 base::Bind(&MediaTransferProtocolManagerImpl::OnReadDirectoryError, |
| 388 weak_ptr_factory_.GetWeakPtr())); | 403 weak_ptr_factory_.GetWeakPtr())); |
| 389 } | 404 } |
| 390 | 405 |
| 391 void OnGotDirectoryEntries(const std::string& storage_handle, | 406 void OnGotDirectoryEntries(const std::string& storage_handle, |
| 392 const std::vector<uint32>& file_ids, | 407 const std::vector<uint32>& file_ids, |
| 393 size_t offset, | 408 const size_t offset, |
| 409 const size_t max_size, | |
| 394 const std::vector<uint32>& sorted_file_ids, | 410 const std::vector<uint32>& sorted_file_ids, |
| 395 const std::vector<MtpFileEntry>& file_entries) { | 411 const std::vector<MtpFileEntry>& file_entries) { |
| 396 DCHECK(thread_checker_.CalledOnValidThread()); | 412 DCHECK(thread_checker_.CalledOnValidThread()); |
| 397 DCHECK_EQ(file_ids.size(), sorted_file_ids.size()); | 413 DCHECK_EQ(file_ids.size(), sorted_file_ids.size()); |
| 398 | 414 |
| 399 // Use |sorted_file_ids| to sanity check and make sure the results are a | 415 // Use |sorted_file_ids| to sanity check and make sure the results are a |
| 400 // subset of the requested file ids. | 416 // subset of the requested file ids. |
| 401 for (size_t i = 0; i < file_entries.size(); ++i) { | 417 for (size_t i = 0; i < file_entries.size(); ++i) { |
| 402 std::vector<uint32>::const_iterator it = | 418 std::vector<uint32>::const_iterator it = |
| 403 std::lower_bound(sorted_file_ids.begin(), | 419 std::lower_bound(sorted_file_ids.begin(), |
| 404 sorted_file_ids.end(), | 420 sorted_file_ids.end(), |
| 405 file_entries[i].item_id()); | 421 file_entries[i].item_id()); |
| 406 if (it == sorted_file_ids.end()) { | 422 if (it == sorted_file_ids.end()) { |
| 407 OnReadDirectoryError(); | 423 OnReadDirectoryError(); |
| 408 return; | 424 return; |
| 409 } | 425 } |
| 410 } | 426 } |
| 411 | 427 |
| 412 size_t next_offset = file_ids.size(); | 428 const size_t directory_size = |
| 429 max_size == 0 ? file_ids.size() : std::min(file_ids.size(), max_size); | |
| 430 size_t next_offset = directory_size; | |
| 413 if (offset < SIZE_MAX - kFileInfoToFetchChunkSize) | 431 if (offset < SIZE_MAX - kFileInfoToFetchChunkSize) |
| 414 next_offset = std::min(next_offset, offset + kFileInfoToFetchChunkSize); | 432 next_offset = std::min(next_offset, offset + kFileInfoToFetchChunkSize); |
| 415 bool has_more = next_offset < file_ids.size(); | 433 bool has_more = next_offset < directory_size; |
| 416 read_directory_callbacks_.front().Run(file_entries, | 434 read_directory_callbacks_.front().Run(file_entries, |
| 417 has_more, | 435 has_more, |
| 418 false /* no error */); | 436 false /* no error */); |
| 437 | |
| 419 if (has_more) { | 438 if (has_more) { |
| 439 const size_t chunk_size = | |
| 440 next_offset + kFileInfoToFetchChunkSize > directory_size | |
|
Lei Zhang
2015/03/10 08:12:05
This is just std::min(directory_size - next_offset
yawano
2015/03/10 08:20:36
Done.
| |
| 441 ? directory_size - next_offset | |
| 442 : kFileInfoToFetchChunkSize; | |
| 443 | |
| 420 mtp_client_->GetFileInfo( | 444 mtp_client_->GetFileInfo( |
| 421 storage_handle, | 445 storage_handle, file_ids, next_offset, chunk_size, |
| 422 file_ids, | |
| 423 next_offset, | |
| 424 kFileInfoToFetchChunkSize, | |
| 425 base::Bind(&MediaTransferProtocolManagerImpl::OnGotDirectoryEntries, | 446 base::Bind(&MediaTransferProtocolManagerImpl::OnGotDirectoryEntries, |
| 426 weak_ptr_factory_.GetWeakPtr(), | 447 weak_ptr_factory_.GetWeakPtr(), storage_handle, file_ids, |
| 427 storage_handle, | 448 next_offset, max_size, sorted_file_ids), |
| 428 file_ids, | |
| 429 next_offset, | |
| 430 sorted_file_ids), | |
| 431 base::Bind(&MediaTransferProtocolManagerImpl::OnReadDirectoryError, | 449 base::Bind(&MediaTransferProtocolManagerImpl::OnReadDirectoryError, |
| 432 weak_ptr_factory_.GetWeakPtr())); | 450 weak_ptr_factory_.GetWeakPtr())); |
| 433 return; | 451 return; |
| 434 } | 452 } |
| 435 read_directory_callbacks_.pop(); | 453 read_directory_callbacks_.pop(); |
| 436 } | 454 } |
| 437 | 455 |
| 438 void OnReadDirectoryError() { | 456 void OnReadDirectoryError() { |
| 439 DCHECK(thread_checker_.CalledOnValidThread()); | 457 DCHECK(thread_checker_.CalledOnValidThread()); |
| 440 read_directory_callbacks_.front().Run(std::vector<MtpFileEntry>(), | 458 read_directory_callbacks_.front().Run(std::vector<MtpFileEntry>(), |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 476 copy_file_from_local_callbacks_.front().Run(false /* no error */); | 494 copy_file_from_local_callbacks_.front().Run(false /* no error */); |
| 477 copy_file_from_local_callbacks_.pop(); | 495 copy_file_from_local_callbacks_.pop(); |
| 478 } | 496 } |
| 479 | 497 |
| 480 void OnCopyFileFromLocalError() { | 498 void OnCopyFileFromLocalError() { |
| 481 DCHECK(thread_checker_.CalledOnValidThread()); | 499 DCHECK(thread_checker_.CalledOnValidThread()); |
| 482 copy_file_from_local_callbacks_.front().Run(true /* error */); | 500 copy_file_from_local_callbacks_.front().Run(true /* error */); |
| 483 copy_file_from_local_callbacks_.pop(); | 501 copy_file_from_local_callbacks_.pop(); |
| 484 } | 502 } |
| 485 | 503 |
| 504 void OnDeleteObject() { | |
| 505 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 506 delete_object_callbacks_.front().Run(false /* no error */); | |
| 507 delete_object_callbacks_.pop(); | |
| 508 } | |
| 509 | |
| 510 void OnDeleteObjectError() { | |
| 511 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 512 delete_object_callbacks_.front().Run(true /* error */); | |
| 513 delete_object_callbacks_.pop(); | |
| 514 } | |
| 515 | |
| 486 // Get the Bus object used to communicate with mtpd. | 516 // Get the Bus object used to communicate with mtpd. |
| 487 dbus::Bus* GetBus() { | 517 dbus::Bus* GetBus() { |
| 488 DCHECK(thread_checker_.CalledOnValidThread()); | 518 DCHECK(thread_checker_.CalledOnValidThread()); |
| 489 #if defined(OS_CHROMEOS) | 519 #if defined(OS_CHROMEOS) |
| 490 return chromeos::DBusThreadManager::Get()->GetSystemBus(); | 520 return chromeos::DBusThreadManager::Get()->GetSystemBus(); |
| 491 #else | 521 #else |
| 492 return session_bus_.get(); | 522 return session_bus_.get(); |
| 493 #endif | 523 #endif |
| 494 } | 524 } |
| 495 | 525 |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 558 | 588 |
| 559 std::string current_mtpd_owner_; | 589 std::string current_mtpd_owner_; |
| 560 | 590 |
| 561 // Queued callbacks. | 591 // Queued callbacks. |
| 562 OpenStorageCallbackQueue open_storage_callbacks_; | 592 OpenStorageCallbackQueue open_storage_callbacks_; |
| 563 CloseStorageCallbackQueue close_storage_callbacks_; | 593 CloseStorageCallbackQueue close_storage_callbacks_; |
| 564 ReadDirectoryCallbackQueue read_directory_callbacks_; | 594 ReadDirectoryCallbackQueue read_directory_callbacks_; |
| 565 ReadFileCallbackQueue read_file_callbacks_; | 595 ReadFileCallbackQueue read_file_callbacks_; |
| 566 GetFileInfoCallbackQueue get_file_info_callbacks_; | 596 GetFileInfoCallbackQueue get_file_info_callbacks_; |
| 567 CopyFileFromLocalCallbackQueue copy_file_from_local_callbacks_; | 597 CopyFileFromLocalCallbackQueue copy_file_from_local_callbacks_; |
| 598 DeleteObjectCallbackQueue delete_object_callbacks_; | |
| 568 | 599 |
| 569 base::ThreadChecker thread_checker_; | 600 base::ThreadChecker thread_checker_; |
| 570 | 601 |
| 571 base::WeakPtrFactory<MediaTransferProtocolManagerImpl> weak_ptr_factory_; | 602 base::WeakPtrFactory<MediaTransferProtocolManagerImpl> weak_ptr_factory_; |
| 572 | 603 |
| 573 DISALLOW_COPY_AND_ASSIGN(MediaTransferProtocolManagerImpl); | 604 DISALLOW_COPY_AND_ASSIGN(MediaTransferProtocolManagerImpl); |
| 574 }; | 605 }; |
| 575 | 606 |
| 576 } // namespace | 607 } // namespace |
| 577 | 608 |
| 578 // static | 609 // static |
| 579 MediaTransferProtocolManager* MediaTransferProtocolManager::Initialize( | 610 MediaTransferProtocolManager* MediaTransferProtocolManager::Initialize( |
| 580 scoped_refptr<base::SequencedTaskRunner> task_runner) { | 611 scoped_refptr<base::SequencedTaskRunner> task_runner) { |
| 581 DCHECK(!g_media_transfer_protocol_manager); | 612 DCHECK(!g_media_transfer_protocol_manager); |
| 582 | 613 |
| 583 g_media_transfer_protocol_manager = | 614 g_media_transfer_protocol_manager = |
| 584 new MediaTransferProtocolManagerImpl(task_runner); | 615 new MediaTransferProtocolManagerImpl(task_runner); |
| 585 VLOG(1) << "MediaTransferProtocolManager initialized"; | 616 VLOG(1) << "MediaTransferProtocolManager initialized"; |
| 586 | 617 |
| 587 return g_media_transfer_protocol_manager; | 618 return g_media_transfer_protocol_manager; |
| 588 } | 619 } |
| 589 | 620 |
| 590 } // namespace device | 621 } // namespace device |
| OLD | NEW |