12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file. 42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/media_galleries/linux/mtp_device_delegate_impl_linux.h" 62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include <algorithm> 8116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include <vector> 9a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/bind.h" 11a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/numerics/safe_conversions.h" 12116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "base/strings/string_number_conversions.h" 13116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "base/strings/string_split.h" 14868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_util.h" 152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/media_galleries/linux/mtp_device_task_helper.h" 162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/media_galleries/linux/mtp_device_task_helper_map_service.h" 172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/media_galleries/linux/snapshot_file_details.h" 185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "net/base/io_buffer.h" 19116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "third_party/cros_system_api/dbus/service_constants.h" 202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace { 222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// File path separator constant. 242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kRootPath[] = "/"; 252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Returns the device relative file path given |file_path|. 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// E.g.: If the |file_path| is "/usb:2,2:12345/DCIM" and |registered_dev_path| 282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// is "/usb:2,2:12345", this function returns the device relative path which is 29116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// "DCIM". 30116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// In the special case when |registered_dev_path| and |file_path| are the same, 31116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// return |kRootPath|. 322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)std::string GetDeviceRelativePath(const base::FilePath& registered_dev_path, 332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::FilePath& file_path) { 34e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch DCHECK_CURRENTLY_ON(content::BrowserThread::IO); 352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!registered_dev_path.empty()); 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!file_path.empty()); 37116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch std::string result; 38116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (registered_dev_path == file_path) { 39116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch result = kRootPath; 40116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } else { 41116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch base::FilePath relative_path; 42116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (registered_dev_path.AppendRelativePath(file_path, &relative_path)) { 43116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DCHECK(!relative_path.empty()); 44116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch result = relative_path.value(); 45116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 46116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 47116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return result; 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Returns the MTPDeviceTaskHelper object associated with the MTP device 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// storage. 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// |storage_name| specifies the name of the storage device. 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Returns NULL if the |storage_name| is no longer valid (e.g. because the 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// corresponding storage device is detached, etc). 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)MTPDeviceTaskHelper* GetDeviceTaskHelperForStorage( 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& storage_name) { 58e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch DCHECK_CURRENTLY_ON(content::BrowserThread::UI); 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return MTPDeviceTaskHelperMapService::GetInstance()->GetDeviceTaskHelper( 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) storage_name); 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Opens the storage device for communication. 642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// 652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Called on the UI thread to dispatch the request to the 662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// MediaTransferProtocolManager. 672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// 682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// |storage_name| specifies the name of the storage device. 692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// |reply_callback| is called when the OpenStorage request completes. 702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// |reply_callback| runs on the IO thread. 712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void OpenStorageOnUIThread( 722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& storage_name, 735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const MTPDeviceTaskHelper::OpenStorageCallback& reply_callback) { 74e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch DCHECK_CURRENTLY_ON(content::BrowserThread::UI); 752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MTPDeviceTaskHelper* task_helper = 762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GetDeviceTaskHelperForStorage(storage_name); 772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!task_helper) { 782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) task_helper = 792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MTPDeviceTaskHelperMapService::GetInstance()->CreateDeviceTaskHelper( 802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) storage_name); 812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) task_helper->OpenStorage(storage_name, reply_callback); 832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 85116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// Enumerates the |dir_id| directory file entries. 862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// 872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Called on the UI thread to dispatch the request to the 882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// MediaTransferProtocolManager. 892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// 902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// |storage_name| specifies the name of the storage device. 912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// |success_callback| is called when the ReadDirectory request succeeds. 922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// |error_callback| is called when the ReadDirectory request fails. 932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// |success_callback| and |error_callback| runs on the IO thread. 942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ReadDirectoryOnUIThread( 952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& storage_name, 96116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch uint32 dir_id, 975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const MTPDeviceTaskHelper::ReadDirectorySuccessCallback& success_callback, 985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const MTPDeviceTaskHelper::ErrorCallback& error_callback) { 99e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch DCHECK_CURRENTLY_ON(content::BrowserThread::UI); 1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MTPDeviceTaskHelper* task_helper = 1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GetDeviceTaskHelperForStorage(storage_name); 1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!task_helper) 1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 1045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) task_helper->ReadDirectory(dir_id, success_callback, error_callback); 1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Gets the |file_path| details. 1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// 1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Called on the UI thread to dispatch the request to the 1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// MediaTransferProtocolManager. 1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// 1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// |storage_name| specifies the name of the storage device. 1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// |success_callback| is called when the GetFileInfo request succeeds. 1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// |error_callback| is called when the GetFileInfo request fails. 1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// |success_callback| and |error_callback| runs on the IO thread. 1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void GetFileInfoOnUIThread( 1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& storage_name, 118116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch uint32 file_id, 1195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const MTPDeviceTaskHelper::GetFileInfoSuccessCallback& success_callback, 1205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const MTPDeviceTaskHelper::ErrorCallback& error_callback) { 121e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch DCHECK_CURRENTLY_ON(content::BrowserThread::UI); 1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MTPDeviceTaskHelper* task_helper = 1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GetDeviceTaskHelperForStorage(storage_name); 1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!task_helper) 1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 1265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) task_helper->GetFileInfo(file_id, success_callback, error_callback); 1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copies the contents of |device_file_path| to |snapshot_file_path|. 1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// 1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Called on the UI thread to dispatch the request to the 1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// MediaTransferProtocolManager. 1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// 1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// |storage_name| specifies the name of the storage device. 1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// |device_file_path| specifies the media device file path. 1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// |snapshot_file_path| specifies the platform path of the snapshot file. 1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// |file_size| specifies the number of bytes that will be written to the 1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// snapshot file. 1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// |success_callback| is called when the copy operation succeeds. 1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// |error_callback| is called when the copy operation fails. 1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// |success_callback| and |error_callback| runs on the IO thread. 1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void WriteDataIntoSnapshotFileOnUIThread( 1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& storage_name, 1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const SnapshotRequestInfo& request_info, 1455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const base::File::Info& snapshot_file_info) { 146e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch DCHECK_CURRENTLY_ON(content::BrowserThread::UI); 1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MTPDeviceTaskHelper* task_helper = 1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GetDeviceTaskHelperForStorage(storage_name); 1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!task_helper) 1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) task_helper->WriteDataIntoSnapshotFile(request_info, snapshot_file_info); 1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Copies the contents of |device_file_path| to |snapshot_file_path|. 1555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// 1565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Called on the UI thread to dispatch the request to the 1575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// MediaTransferProtocolManager. 1585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// 1595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// |storage_name| specifies the name of the storage device. 1605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// |request| is a struct containing details about the byte read request. 1615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void ReadBytesOnUIThread( 1625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const std::string& storage_name, 1635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const MTPDeviceAsyncDelegate::ReadBytesRequest& request) { 164e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch DCHECK_CURRENTLY_ON(content::BrowserThread::UI); 1655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) MTPDeviceTaskHelper* task_helper = 1665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) GetDeviceTaskHelperForStorage(storage_name); 1675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!task_helper) 1685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return; 1695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) task_helper->ReadBytes(request); 1705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Closes the device storage specified by the |storage_name| and destroys the 1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// MTPDeviceTaskHelper object associated with the device storage. 1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// 1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Called on the UI thread to dispatch the request to the 1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// MediaTransferProtocolManager. 1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void CloseStorageAndDestroyTaskHelperOnUIThread( 1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& storage_name) { 179e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch DCHECK_CURRENTLY_ON(content::BrowserThread::UI); 1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MTPDeviceTaskHelper* task_helper = 1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GetDeviceTaskHelperForStorage(storage_name); 1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!task_helper) 1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) task_helper->CloseStorage(); 1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MTPDeviceTaskHelperMapService::GetInstance()->DestroyDeviceTaskHelper( 1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) storage_name); 1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace 1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)MTPDeviceDelegateImplLinux::PendingTaskInfo::PendingTaskInfo( 192116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const base::FilePath& path, 193116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch content::BrowserThread::ID thread_id, 1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const tracked_objects::Location& location, 1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::Closure& task) 196116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch : path(path), 197116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch thread_id(thread_id), 198116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch location(location), 1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) task(task) { 2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)MTPDeviceDelegateImplLinux::PendingTaskInfo::~PendingTaskInfo() { 2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 205116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// Represents a file on the MTP device. 206116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// Lives on the IO thread. 207116680a4aac90f2aa7413d9095a592090648e557Ben Murdochclass MTPDeviceDelegateImplLinux::MTPFileNode { 208116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch public: 209116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch MTPFileNode(uint32 file_id, 21003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) const std::string& file_name, 211116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch MTPFileNode* parent, 212116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch FileIdToMTPFileNodeMap* file_id_to_node_map); 213116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ~MTPFileNode(); 214116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 215116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const MTPFileNode* GetChild(const std::string& name) const; 216116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 217116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch void EnsureChildExists(const std::string& name, uint32 id); 218116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 219116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Clears all the children, except those in |children_to_keep|. 220116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch void ClearNonexistentChildren( 221116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const std::set<std::string>& children_to_keep); 222116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 223116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch bool DeleteChild(uint32 file_id); 224116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 225116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch uint32 file_id() const { return file_id_; } 22603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) const std::string& file_name() const { return file_name_; } 227116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch MTPFileNode* parent() { return parent_; } 228116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 229116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch private: 230116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Container for holding a node's children. 231116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch typedef base::ScopedPtrHashMap<std::string, MTPFileNode> ChildNodes; 232116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 233116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const uint32 file_id_; 23403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) const std::string file_name_; 23503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 236116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ChildNodes children_; 237116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch MTPFileNode* const parent_; 238116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch FileIdToMTPFileNodeMap* file_id_to_node_map_; 239116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 240116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DISALLOW_COPY_AND_ASSIGN(MTPFileNode); 241116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}; 242116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 243116680a4aac90f2aa7413d9095a592090648e557Ben MurdochMTPDeviceDelegateImplLinux::MTPFileNode::MTPFileNode( 244116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch uint32 file_id, 24503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) const std::string& file_name, 246116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch MTPFileNode* parent, 247116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch FileIdToMTPFileNodeMap* file_id_to_node_map) 248116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch : file_id_(file_id), 24903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) file_name_(file_name), 250116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch parent_(parent), 251116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch file_id_to_node_map_(file_id_to_node_map) { 252116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DCHECK_CURRENTLY_ON(content::BrowserThread::IO); 253116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DCHECK(file_id_to_node_map_); 254116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DCHECK(!ContainsKey(*file_id_to_node_map_, file_id_)); 255116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch (*file_id_to_node_map_)[file_id_] = this; 256116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 257116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 258116680a4aac90f2aa7413d9095a592090648e557Ben MurdochMTPDeviceDelegateImplLinux::MTPFileNode::~MTPFileNode() { 259116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DCHECK_CURRENTLY_ON(content::BrowserThread::IO); 260116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch size_t erased = file_id_to_node_map_->erase(file_id_); 261116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DCHECK_EQ(1U, erased); 262116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 263116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 264116680a4aac90f2aa7413d9095a592090648e557Ben Murdochconst MTPDeviceDelegateImplLinux::MTPFileNode* 265116680a4aac90f2aa7413d9095a592090648e557Ben MurdochMTPDeviceDelegateImplLinux::MTPFileNode::GetChild( 266116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const std::string& name) const { 267116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DCHECK_CURRENTLY_ON(content::BrowserThread::IO); 268116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return children_.get(name); 269116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 270116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 271116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid MTPDeviceDelegateImplLinux::MTPFileNode::EnsureChildExists( 272116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const std::string& name, 273116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch uint32 id) { 274116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DCHECK_CURRENTLY_ON(content::BrowserThread::IO); 275116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const MTPFileNode* child = GetChild(name); 276116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (child && child->file_id() == id) 277116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return; 278116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 279116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch children_.set( 280116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch name, 28103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) make_scoped_ptr(new MTPFileNode(id, name, this, file_id_to_node_map_))); 282116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 283116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 284116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid MTPDeviceDelegateImplLinux::MTPFileNode::ClearNonexistentChildren( 285116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const std::set<std::string>& children_to_keep) { 286116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DCHECK_CURRENTLY_ON(content::BrowserThread::IO); 287116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch std::set<std::string> children_to_erase; 288116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch for (ChildNodes::const_iterator it = children_.begin(); 289116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch it != children_.end(); ++it) { 290116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (ContainsKey(children_to_keep, it->first)) 291116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch continue; 292116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch children_to_erase.insert(it->first); 293116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 294116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch for (std::set<std::string>::iterator it = children_to_erase.begin(); 295116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch it != children_to_erase.end(); ++it) { 296116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch children_.take_and_erase(*it); 297116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 298116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 299116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 300116680a4aac90f2aa7413d9095a592090648e557Ben Murdochbool MTPDeviceDelegateImplLinux::MTPFileNode::DeleteChild(uint32 file_id) { 301116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DCHECK_CURRENTLY_ON(content::BrowserThread::IO); 302116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch for (ChildNodes::iterator it = children_.begin(); 303116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch it != children_.end(); ++it) { 304116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (it->second->file_id() == file_id) { 305116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch children_.erase(it); 306116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return true; 307116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 308116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 309116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return false; 310116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 311116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)MTPDeviceDelegateImplLinux::MTPDeviceDelegateImplLinux( 3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& device_location) 3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : init_state_(UNINITIALIZED), 3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) task_in_progress_(false), 3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) device_path_(device_location), 317116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch root_node_(new MTPFileNode(mtpd::kRootFileId, 31803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) "", // Root node has no name. 31903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) NULL, // And no parent node. 320116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch &file_id_to_node_map_)), 321c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) weak_ptr_factory_(this) { 322e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch DCHECK_CURRENTLY_ON(content::BrowserThread::IO); 3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!device_path_.empty()); 324a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::RemoveChars(device_location, kRootPath, &storage_name_); 3252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!storage_name_.empty()); 3262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)MTPDeviceDelegateImplLinux::~MTPDeviceDelegateImplLinux() { 329e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch DCHECK_CURRENTLY_ON(content::BrowserThread::IO); 3302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void MTPDeviceDelegateImplLinux::GetFileInfo( 3332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::FilePath& file_path, 3342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const GetFileInfoSuccessCallback& success_callback, 3352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const ErrorCallback& error_callback) { 336e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch DCHECK_CURRENTLY_ON(content::BrowserThread::IO); 3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!file_path.empty()); 33803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 33903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // If a ReadDirectory operation is in progress, the file info may already be 34003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // cached. 34103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) FileInfoCache::const_iterator it = file_info_cache_.find(file_path); 34203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (it != file_info_cache_.end()) { 34303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // TODO(thestig): This code is repeated in several places. Combine them. 34403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // e.g. c/b/media_galleries/win/mtp_device_operations_util.cc 34503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) const storage::DirectoryEntry& cached_file_entry = it->second; 34603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) base::File::Info info; 34703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) info.size = cached_file_entry.size; 34803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) info.is_directory = cached_file_entry.is_directory; 34903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) info.is_symbolic_link = false; 35003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) info.last_modified = cached_file_entry.last_modified_time; 35103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) info.creation_time = base::Time(); 35203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 35303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) success_callback.Run(info); 35403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) return; 35503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) } 356116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch base::Closure closure = 357116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch base::Bind(&MTPDeviceDelegateImplLinux::GetFileInfoInternal, 358116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch weak_ptr_factory_.GetWeakPtr(), 359116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch file_path, 360116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch success_callback, 361116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch error_callback); 362116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EnsureInitAndRunTask(PendingTaskInfo(file_path, 363116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch content::BrowserThread::IO, 364116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch FROM_HERE, 365116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch closure)); 3662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void MTPDeviceDelegateImplLinux::ReadDirectory( 3692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::FilePath& root, 3702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const ReadDirectorySuccessCallback& success_callback, 3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const ErrorCallback& error_callback) { 372e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch DCHECK_CURRENTLY_ON(content::BrowserThread::IO); 3732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!root.empty()); 374116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch base::Closure closure = 375116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch base::Bind(&MTPDeviceDelegateImplLinux::ReadDirectoryInternal, 376116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch weak_ptr_factory_.GetWeakPtr(), 377116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch root, 378116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch success_callback, 379116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch error_callback); 380116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EnsureInitAndRunTask(PendingTaskInfo(root, 381116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch content::BrowserThread::IO, 382116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch FROM_HERE, 383116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch closure)); 3842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void MTPDeviceDelegateImplLinux::CreateSnapshotFile( 3872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::FilePath& device_file_path, 388116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const base::FilePath& local_path, 3892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const CreateSnapshotFileSuccessCallback& success_callback, 3902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const ErrorCallback& error_callback) { 391e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch DCHECK_CURRENTLY_ON(content::BrowserThread::IO); 3922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!device_file_path.empty()); 393116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DCHECK(!local_path.empty()); 394116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch base::Closure closure = 395116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch base::Bind(&MTPDeviceDelegateImplLinux::CreateSnapshotFileInternal, 396116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch weak_ptr_factory_.GetWeakPtr(), 397116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch device_file_path, 398116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch local_path, 399116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch success_callback, 400116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch error_callback); 401116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EnsureInitAndRunTask(PendingTaskInfo(device_file_path, 402116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch content::BrowserThread::IO, 403116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch FROM_HERE, 404116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch closure)); 4052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool MTPDeviceDelegateImplLinux::IsStreaming() { 408a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return true; 4095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 4105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void MTPDeviceDelegateImplLinux::ReadBytes( 4125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const base::FilePath& device_file_path, 4131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const scoped_refptr<net::IOBuffer>& buf, 4141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci int64 offset, 4151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci int buf_len, 4165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const ReadBytesSuccessCallback& success_callback, 4175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const ErrorCallback& error_callback) { 418e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch DCHECK_CURRENTLY_ON(content::BrowserThread::IO); 4195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(!device_file_path.empty()); 420116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch base::Closure closure = 421116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch base::Bind(&MTPDeviceDelegateImplLinux::ReadBytesInternal, 422116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch weak_ptr_factory_.GetWeakPtr(), 423116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch device_file_path, 4241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci buf, 425116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch offset, 426116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch buf_len, 427116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch success_callback, 428116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch error_callback); 429116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EnsureInitAndRunTask(PendingTaskInfo(device_file_path, 430116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch content::BrowserThread::IO, 431116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch FROM_HERE, 432116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch closure)); 4335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 4345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void MTPDeviceDelegateImplLinux::CancelPendingTasksAndDeleteDelegate() { 436e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch DCHECK_CURRENTLY_ON(content::BrowserThread::IO); 4372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // To cancel all the pending tasks, destroy the MTPDeviceTaskHelper object. 4382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) content::BrowserThread::PostTask( 4392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) content::BrowserThread::UI, 4402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 4412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&CloseStorageAndDestroyTaskHelperOnUIThread, storage_name_)); 4422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) delete this; 4432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 445116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid MTPDeviceDelegateImplLinux::GetFileInfoInternal( 446116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const base::FilePath& file_path, 447116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const GetFileInfoSuccessCallback& success_callback, 448116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const ErrorCallback& error_callback) { 449116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DCHECK_CURRENTLY_ON(content::BrowserThread::IO); 450116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 451116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch uint32 file_id; 452116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (CachedPathToId(file_path, &file_id)) { 453116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch GetFileInfoSuccessCallback success_callback_wrapper = 454116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch base::Bind(&MTPDeviceDelegateImplLinux::OnDidGetFileInfo, 455116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch weak_ptr_factory_.GetWeakPtr(), 456116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch success_callback); 457116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ErrorCallback error_callback_wrapper = 458116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch base::Bind(&MTPDeviceDelegateImplLinux::HandleDeviceFileError, 459116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch weak_ptr_factory_.GetWeakPtr(), 460116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch error_callback, 461116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch file_id); 462116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 463116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 464116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch base::Closure closure = base::Bind(&GetFileInfoOnUIThread, 465116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch storage_name_, 466116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch file_id, 467116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch success_callback_wrapper, 468116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch error_callback_wrapper); 469116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EnsureInitAndRunTask(PendingTaskInfo(base::FilePath(), 470116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch content::BrowserThread::UI, 471116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch FROM_HERE, 472116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch closure)); 473116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } else { 474116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch error_callback.Run(base::File::FILE_ERROR_NOT_FOUND); 475116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 476116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch PendingRequestDone(); 477116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 478116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 479116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid MTPDeviceDelegateImplLinux::ReadDirectoryInternal( 480116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const base::FilePath& root, 481116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const ReadDirectorySuccessCallback& success_callback, 482116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const ErrorCallback& error_callback) { 483116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DCHECK_CURRENTLY_ON(content::BrowserThread::IO); 484116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 485116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch uint32 dir_id; 486116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (CachedPathToId(root, &dir_id)) { 487116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch GetFileInfoSuccessCallback success_callback_wrapper = 488116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch base::Bind(&MTPDeviceDelegateImplLinux::OnDidGetFileInfoToReadDirectory, 489116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch weak_ptr_factory_.GetWeakPtr(), 490116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch dir_id, 491116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch success_callback, 492116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch error_callback); 493116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ErrorCallback error_callback_wrapper = 494116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch base::Bind(&MTPDeviceDelegateImplLinux::HandleDeviceFileError, 495116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch weak_ptr_factory_.GetWeakPtr(), 496116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch error_callback, 497116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch dir_id); 498116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch base::Closure closure = base::Bind(&GetFileInfoOnUIThread, 499116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch storage_name_, 500116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch dir_id, 501116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch success_callback_wrapper, 502116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch error_callback_wrapper); 503116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EnsureInitAndRunTask(PendingTaskInfo(base::FilePath(), 504116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch content::BrowserThread::UI, 505116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch FROM_HERE, 506116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch closure)); 507116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } else { 508116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch error_callback.Run(base::File::FILE_ERROR_NOT_FOUND); 509116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 510116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch PendingRequestDone(); 511116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 512116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 513116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid MTPDeviceDelegateImplLinux::CreateSnapshotFileInternal( 514116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const base::FilePath& device_file_path, 515116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const base::FilePath& local_path, 516116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const CreateSnapshotFileSuccessCallback& success_callback, 517116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const ErrorCallback& error_callback) { 518116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DCHECK_CURRENTLY_ON(content::BrowserThread::IO); 519116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 520116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch uint32 file_id; 521116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (CachedPathToId(device_file_path, &file_id)) { 522116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch scoped_ptr<SnapshotRequestInfo> request_info( 523116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch new SnapshotRequestInfo(file_id, 524116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch local_path, 525116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch success_callback, 526116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch error_callback)); 527116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch GetFileInfoSuccessCallback success_callback_wrapper = 528116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch base::Bind( 529116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch &MTPDeviceDelegateImplLinux::OnDidGetFileInfoToCreateSnapshotFile, 530116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch weak_ptr_factory_.GetWeakPtr(), 531116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch base::Passed(&request_info)); 532116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ErrorCallback error_callback_wrapper = 533116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch base::Bind(&MTPDeviceDelegateImplLinux::HandleDeviceFileError, 534116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch weak_ptr_factory_.GetWeakPtr(), 535116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch error_callback, 536116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch file_id); 537116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch base::Closure closure = base::Bind(&GetFileInfoOnUIThread, 538116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch storage_name_, 539116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch file_id, 540116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch success_callback_wrapper, 541116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch error_callback_wrapper); 542116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EnsureInitAndRunTask(PendingTaskInfo(base::FilePath(), 543116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch content::BrowserThread::UI, 544116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch FROM_HERE, 545116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch closure)); 546116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } else { 547116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch error_callback.Run(base::File::FILE_ERROR_NOT_FOUND); 548116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 549116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch PendingRequestDone(); 550116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 551116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 552116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid MTPDeviceDelegateImplLinux::ReadBytesInternal( 553116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const base::FilePath& device_file_path, 554116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch net::IOBuffer* buf, int64 offset, int buf_len, 555116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const ReadBytesSuccessCallback& success_callback, 556116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const ErrorCallback& error_callback) { 557116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DCHECK_CURRENTLY_ON(content::BrowserThread::IO); 558116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 559116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch uint32 file_id; 560116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (CachedPathToId(device_file_path, &file_id)) { 561116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ReadBytesRequest request( 562116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch file_id, buf, offset, buf_len, 563116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch base::Bind(&MTPDeviceDelegateImplLinux::OnDidReadBytes, 564116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch weak_ptr_factory_.GetWeakPtr(), 565116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch success_callback), 566116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch base::Bind(&MTPDeviceDelegateImplLinux::HandleDeviceFileError, 567116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch weak_ptr_factory_.GetWeakPtr(), 568116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch error_callback, 569116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch file_id)); 570116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 571116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch base::Closure closure = 572116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch base::Bind(base::Bind(&ReadBytesOnUIThread, storage_name_, request)); 573116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EnsureInitAndRunTask(PendingTaskInfo(base::FilePath(), 574116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch content::BrowserThread::UI, 575116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch FROM_HERE, 576116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch closure)); 577116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } else { 578116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch error_callback.Run(base::File::FILE_ERROR_NOT_FOUND); 579116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 580116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch PendingRequestDone(); 581116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 582116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 5832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void MTPDeviceDelegateImplLinux::EnsureInitAndRunTask( 5842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const PendingTaskInfo& task_info) { 585e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch DCHECK_CURRENTLY_ON(content::BrowserThread::IO); 5862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if ((init_state_ == INITIALIZED) && !task_in_progress_) { 587116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch RunTask(task_info); 5882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 5892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 590116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 591116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Only *Internal functions have empty paths. Since they are the continuation 592116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // of the current running task, they get to cut in line. 593116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (task_info.path.empty()) 594116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch pending_tasks_.push_front(task_info); 595116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch else 596116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch pending_tasks_.push_back(task_info); 597116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 5982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (init_state_ == UNINITIALIZED) { 5992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) init_state_ = PENDING_INIT; 6002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) task_in_progress_ = true; 6012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) content::BrowserThread::PostTask( 6022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) content::BrowserThread::UI, 6032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 6042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&OpenStorageOnUIThread, 6052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) storage_name_, 6062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&MTPDeviceDelegateImplLinux::OnInitCompleted, 6072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) weak_ptr_factory_.GetWeakPtr()))); 6082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 6092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 6102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 611116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid MTPDeviceDelegateImplLinux::RunTask(const PendingTaskInfo& task_info) { 612116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DCHECK_CURRENTLY_ON(content::BrowserThread::IO); 613116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DCHECK_EQ(INITIALIZED, init_state_); 614116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DCHECK(!task_in_progress_); 615116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch task_in_progress_ = true; 616116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 617116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch bool need_to_check_cache = !task_info.path.empty(); 618116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (need_to_check_cache) { 619116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch base::FilePath uncached_path = 620116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch NextUncachedPathComponent(task_info.path, task_info.cached_path); 621116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (!uncached_path.empty()) { 622116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Save the current task and do a cache lookup first. 623116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch pending_tasks_.push_front(task_info); 624116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch FillFileCache(uncached_path); 625116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return; 626116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 627116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 628116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 629116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch content::BrowserThread::PostTask(task_info.thread_id, 630116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch task_info.location, 631116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch task_info.task); 632116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 633116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 6342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void MTPDeviceDelegateImplLinux::WriteDataIntoSnapshotFile( 6355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const base::File::Info& file_info) { 636e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch DCHECK_CURRENTLY_ON(content::BrowserThread::IO); 6372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(current_snapshot_request_info_.get()); 6382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK_GT(file_info.size, 0); 639116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DCHECK(task_in_progress_); 6402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SnapshotRequestInfo request_info( 641116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch current_snapshot_request_info_->file_id, 6422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) current_snapshot_request_info_->snapshot_file_path, 6432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind( 6442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &MTPDeviceDelegateImplLinux::OnDidWriteDataIntoSnapshotFile, 6452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) weak_ptr_factory_.GetWeakPtr()), 6462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind( 6472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &MTPDeviceDelegateImplLinux::OnWriteDataIntoSnapshotFileError, 6482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) weak_ptr_factory_.GetWeakPtr())); 6492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Closure task_closure = base::Bind(&WriteDataIntoSnapshotFileOnUIThread, 6512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) storage_name_, 6522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) request_info, 6532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) file_info); 6542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) content::BrowserThread::PostTask(content::BrowserThread::UI, 6552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 6562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) task_closure); 6572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 6582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 659116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid MTPDeviceDelegateImplLinux::PendingRequestDone() { 660116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DCHECK(task_in_progress_); 661116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch task_in_progress_ = false; 662116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ProcessNextPendingRequest(); 663116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 664116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 6652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void MTPDeviceDelegateImplLinux::ProcessNextPendingRequest() { 666e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch DCHECK_CURRENTLY_ON(content::BrowserThread::IO); 6672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!task_in_progress_); 6682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (pending_tasks_.empty()) 6692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 6702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 671116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch PendingTaskInfo task_info = pending_tasks_.front(); 672116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch pending_tasks_.pop_front(); 673116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch RunTask(task_info); 6742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 6752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void MTPDeviceDelegateImplLinux::OnInitCompleted(bool succeeded) { 677e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch DCHECK_CURRENTLY_ON(content::BrowserThread::IO); 6782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) init_state_ = succeeded ? INITIALIZED : UNINITIALIZED; 679116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch PendingRequestDone(); 6802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 6812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void MTPDeviceDelegateImplLinux::OnDidGetFileInfo( 6832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const GetFileInfoSuccessCallback& success_callback, 6845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const base::File::Info& file_info) { 685e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch DCHECK_CURRENTLY_ON(content::BrowserThread::IO); 6862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) success_callback.Run(file_info); 687116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch PendingRequestDone(); 6882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 6892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void MTPDeviceDelegateImplLinux::OnDidGetFileInfoToReadDirectory( 691116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch uint32 dir_id, 6922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const ReadDirectorySuccessCallback& success_callback, 6932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const ErrorCallback& error_callback, 6945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const base::File::Info& file_info) { 695e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch DCHECK_CURRENTLY_ON(content::BrowserThread::IO); 6962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(task_in_progress_); 6972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!file_info.is_directory) { 6982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return HandleDeviceFileError(error_callback, 699116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch dir_id, 7005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::File::FILE_ERROR_NOT_A_DIRECTORY); 7012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 7022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Closure task_closure = 7042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&ReadDirectoryOnUIThread, 7052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) storage_name_, 706116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch dir_id, 7072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&MTPDeviceDelegateImplLinux::OnDidReadDirectory, 7082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) weak_ptr_factory_.GetWeakPtr(), 709116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch dir_id, 7102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) success_callback), 7112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&MTPDeviceDelegateImplLinux::HandleDeviceFileError, 7122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) weak_ptr_factory_.GetWeakPtr(), 713116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch error_callback, 714116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch dir_id)); 7152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) content::BrowserThread::PostTask(content::BrowserThread::UI, 7162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 7172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) task_closure); 7182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 7192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void MTPDeviceDelegateImplLinux::OnDidGetFileInfoToCreateSnapshotFile( 7212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<SnapshotRequestInfo> snapshot_request_info, 7225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const base::File::Info& file_info) { 723e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch DCHECK_CURRENTLY_ON(content::BrowserThread::IO); 7242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!current_snapshot_request_info_.get()); 7252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(snapshot_request_info.get()); 7262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(task_in_progress_); 7275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::File::Error error = base::File::FILE_OK; 7282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (file_info.is_directory) 7295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) error = base::File::FILE_ERROR_NOT_A_FILE; 7302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) else if (file_info.size < 0 || file_info.size > kuint32max) 7315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) error = base::File::FILE_ERROR_FAILED; 7322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (error != base::File::FILE_OK) 734116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return HandleDeviceFileError(snapshot_request_info->error_callback, 735116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch snapshot_request_info->file_id, 736116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch error); 7372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::File::Info snapshot_file_info(file_info); 7392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Modify the last modified time to null. This prevents the time stamp 7402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // verfication in LocalFileStreamReader. 7412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) snapshot_file_info.last_modified = base::Time(); 7422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) current_snapshot_request_info_.reset(snapshot_request_info.release()); 7442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (file_info.size == 0) { 7452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Empty snapshot file. 7462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return OnDidWriteDataIntoSnapshotFile( 747c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) snapshot_file_info, current_snapshot_request_info_->snapshot_file_path); 7482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 7492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) WriteDataIntoSnapshotFile(snapshot_file_info); 7502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 7512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void MTPDeviceDelegateImplLinux::OnDidReadDirectory( 753116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch uint32 dir_id, 7542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const ReadDirectorySuccessCallback& success_callback, 75503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) const storage::AsyncFileUtil::EntryList& file_list, 7565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) bool has_more) { 757e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch DCHECK_CURRENTLY_ON(content::BrowserThread::IO); 758116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 759116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch FileIdToMTPFileNodeMap::iterator it = file_id_to_node_map_.find(dir_id); 760116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DCHECK(it != file_id_to_node_map_.end()); 761116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch MTPFileNode* dir_node = it->second; 762116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 76303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // Traverse the MTPFileNode tree to reconstuct the full path for |dir_id|. 76403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) std::deque<std::string> dir_path_parts; 76503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) MTPFileNode* parent_node = dir_node; 76603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) while (parent_node->parent()) { 76703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) dir_path_parts.push_front(parent_node->file_name()); 76803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) parent_node = parent_node->parent(); 76903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) } 77003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) base::FilePath dir_path = device_path_; 77103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) for (size_t i = 0; i < dir_path_parts.size(); ++i) 77203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) dir_path = dir_path.Append(dir_path_parts[i]); 77303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 77403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) storage::AsyncFileUtil::EntryList normalized_file_list; 775116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch for (size_t i = 0; i < file_list.size(); ++i) { 776116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch normalized_file_list.push_back(file_list[i]); 77703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) storage::DirectoryEntry& entry = normalized_file_list.back(); 778116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 779116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // |entry.name| has the file id encoded in it. Decode here. 780116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch size_t separator_idx = entry.name.find_last_of(','); 781116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DCHECK_NE(std::string::npos, separator_idx); 782116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch std::string file_id_str = entry.name.substr(separator_idx); 783116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch file_id_str = file_id_str.substr(1); // Get rid of the comma. 784116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch uint32 file_id = 0; 785116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch bool ret = base::StringToUint(file_id_str, &file_id); 786116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DCHECK(ret); 787116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch entry.name = entry.name.substr(0, separator_idx); 788116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 789116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Refresh the in memory tree. 790116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch dir_node->EnsureChildExists(entry.name, file_id); 7915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) child_nodes_seen_.insert(entry.name); 79203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 79303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // Add to |file_info_cache_|. 79403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) file_info_cache_[dir_path.Append(entry.name)] = entry; 795116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 796116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 7975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) success_callback.Run(normalized_file_list, has_more); 7985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (has_more) 7995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return; // Wait to be called again. 8005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 8015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // Last call, finish book keeping and continue with the next request. 8025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) dir_node->ClearNonexistentChildren(child_nodes_seen_); 8035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) child_nodes_seen_.clear(); 80403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) file_info_cache_.clear(); 8055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 806116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch PendingRequestDone(); 8072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 8082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void MTPDeviceDelegateImplLinux::OnDidWriteDataIntoSnapshotFile( 8105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const base::File::Info& file_info, 8112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::FilePath& snapshot_file_path) { 812e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch DCHECK_CURRENTLY_ON(content::BrowserThread::IO); 8132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(current_snapshot_request_info_.get()); 8142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) current_snapshot_request_info_->success_callback.Run( 8152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) file_info, snapshot_file_path); 8162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) current_snapshot_request_info_.reset(); 817116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch PendingRequestDone(); 8182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 8192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void MTPDeviceDelegateImplLinux::OnWriteDataIntoSnapshotFileError( 8215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::File::Error error) { 822e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch DCHECK_CURRENTLY_ON(content::BrowserThread::IO); 8232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(current_snapshot_request_info_.get()); 8242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) current_snapshot_request_info_->error_callback.Run(error); 8252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) current_snapshot_request_info_.reset(); 826116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch PendingRequestDone(); 8272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 8282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void MTPDeviceDelegateImplLinux::OnDidReadBytes( 8305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const ReadBytesSuccessCallback& success_callback, 831a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const base::File::Info& file_info, int bytes_read) { 832e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch DCHECK_CURRENTLY_ON(content::BrowserThread::IO); 833a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) success_callback.Run(file_info, bytes_read); 834116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch PendingRequestDone(); 835116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 836116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 837116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid MTPDeviceDelegateImplLinux::OnDidFillFileCache( 838116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const base::FilePath& path, 83903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) const storage::AsyncFileUtil::EntryList& /* file_list */, 8405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) bool has_more) { 841116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DCHECK_CURRENTLY_ON(content::BrowserThread::IO); 842116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DCHECK(path.IsParent(pending_tasks_.front().path)); 8435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (has_more) 8445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return; // Wait until all entries have been read. 845116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch pending_tasks_.front().cached_path = path; 846116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 847116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 848116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid MTPDeviceDelegateImplLinux::OnFillFileCacheFailed( 849116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch base::File::Error /* error */) { 850116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DCHECK_CURRENTLY_ON(content::BrowserThread::IO); 851116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // When filling the cache fails for the task at the front of the queue, clear 852116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // the path of the task so it will not try to do any more caching. Instead, 853116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // the task will just run and fail the CachedPathToId() lookup. 854116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch pending_tasks_.front().path.clear(); 8555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 8565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 8572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void MTPDeviceDelegateImplLinux::HandleDeviceFileError( 8582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const ErrorCallback& error_callback, 859116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch uint32 file_id, 8605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::File::Error error) { 861e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch DCHECK_CURRENTLY_ON(content::BrowserThread::IO); 862116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 863116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch FileIdToMTPFileNodeMap::iterator it = file_id_to_node_map_.find(file_id); 864116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (it != file_id_to_node_map_.end()) { 865116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch MTPFileNode* parent = it->second->parent(); 866116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (parent) { 867116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch bool ret = parent->DeleteChild(file_id); 868116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DCHECK(ret); 869116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 870116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 8712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) error_callback.Run(error); 872116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch PendingRequestDone(); 873116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 874116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 875116680a4aac90f2aa7413d9095a592090648e557Ben Murdochbase::FilePath MTPDeviceDelegateImplLinux::NextUncachedPathComponent( 876116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const base::FilePath& path, 877116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const base::FilePath& cached_path) const { 878116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DCHECK_CURRENTLY_ON(content::BrowserThread::IO); 879116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DCHECK(cached_path.empty() || cached_path.IsParent(path)); 880116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 881116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch base::FilePath uncached_path; 882116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch std::string device_relpath = GetDeviceRelativePath(device_path_, path); 883116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (!device_relpath.empty() && device_relpath != kRootPath) { 884116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch uncached_path = device_path_; 885116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch std::vector<std::string> device_relpath_components; 886116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch base::SplitString(device_relpath, '/', &device_relpath_components); 887116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DCHECK(!device_relpath_components.empty()); 888116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch bool all_components_cached = true; 889116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const MTPFileNode* current_node = root_node_.get(); 890116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch for (size_t i = 0; i < device_relpath_components.size(); ++i) { 891116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch current_node = current_node->GetChild(device_relpath_components[i]); 892116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (!current_node) { 893116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // With a cache miss, check if it is a genuine failure. If so, pretend 894116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // the entire |path| is cached, so there is no further attempt to do 895116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // more caching. The actual operation will then fail. 896116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch all_components_cached = 897116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch !cached_path.empty() && (uncached_path == cached_path); 898116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch break; 899116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 900116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch uncached_path = uncached_path.Append(device_relpath_components[i]); 901116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 902116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (all_components_cached) 903116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch uncached_path.clear(); 904116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 905116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return uncached_path; 906116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 907116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 908116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid MTPDeviceDelegateImplLinux::FillFileCache( 909116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const base::FilePath& uncached_path) { 910116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DCHECK_CURRENTLY_ON(content::BrowserThread::IO); 911116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DCHECK(task_in_progress_); 912116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 913116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ReadDirectorySuccessCallback success_callback = 914116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch base::Bind(&MTPDeviceDelegateImplLinux::OnDidFillFileCache, 915116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch weak_ptr_factory_.GetWeakPtr(), 916116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch uncached_path); 917116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ErrorCallback error_callback = 918116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch base::Bind(&MTPDeviceDelegateImplLinux::OnFillFileCacheFailed, 919116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch weak_ptr_factory_.GetWeakPtr()); 920116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ReadDirectoryInternal(uncached_path, success_callback, error_callback); 921116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 922116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 923116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 924116680a4aac90f2aa7413d9095a592090648e557Ben Murdochbool MTPDeviceDelegateImplLinux::CachedPathToId(const base::FilePath& path, 925116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch uint32* id) const { 926116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DCHECK(id); 927116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 928116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch std::string device_relpath = GetDeviceRelativePath(device_path_, path); 929116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (device_relpath.empty()) 930116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return false; 931116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch std::vector<std::string> device_relpath_components; 932116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (device_relpath != kRootPath) 933116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch base::SplitString(device_relpath, '/', &device_relpath_components); 934116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const MTPFileNode* current_node = root_node_.get(); 935116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch for (size_t i = 0; i < device_relpath_components.size(); ++i) { 936116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch current_node = current_node->GetChild(device_relpath_components[i]); 937116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (!current_node) 938116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return false; 939116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 940116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch *id = current_node->file_id(); 941116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return true; 9422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 9432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 9442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void CreateMTPDeviceAsyncDelegate( 9452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& device_location, 9462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const CreateMTPDeviceAsyncDelegateCallback& callback) { 947e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch DCHECK_CURRENTLY_ON(content::BrowserThread::IO); 9482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) callback.Run(new MTPDeviceDelegateImplLinux(device_location)); 9492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 950