15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/chromeos/drive/file_system/copy_operation.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <string> 82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "base/task_runner_util.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/chromeos/drive/drive.pb.h" 11c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/chromeos/drive/file_cache.h" 12116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "chrome/browser/chromeos/drive/file_change.h" 13c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/chromeos/drive/file_system/create_file_operation.h" 145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "chrome/browser/chromeos/drive/file_system/operation_delegate.h" 15c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/chromeos/drive/file_system_util.h" 16c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/chromeos/drive/job_scheduler.h" 172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/chromeos/drive/resource_entry_conversion.h" 18a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "chrome/browser/chromeos/drive/resource_metadata.h" 19eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "chrome/browser/drive/drive_api_util.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/browser_thread.h" 21a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "google_apis/drive/drive_api_parser.h" 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::BrowserThread; 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace drive { 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace file_system { 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)struct CopyOperation::CopyParams { 295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::FilePath src_file_path; 305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::FilePath dest_file_path; 315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool preserve_last_modified; 325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) FileOperationCallback callback; 335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ResourceEntry src_entry; 345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ResourceEntry parent_entry; 355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}; 365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 37a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Enum for categorizing where a gdoc represented by a JSON file exists. 38a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)enum JsonGdocLocationType { 39a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) NOT_IN_METADATA, 40a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) IS_ORPHAN, 41a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) HAS_PARENT, 42a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}; 43a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 44a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)struct CopyOperation::TransferJsonGdocParams { 45a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TransferJsonGdocParams(const FileOperationCallback& callback, 46a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const std::string& resource_id, 47a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const ResourceEntry& parent_entry, 48a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const std::string& new_title) 49a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) : callback(callback), 50a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) resource_id(resource_id), 51a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) parent_resource_id(parent_entry.resource_id()), 52a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) parent_local_id(parent_entry.local_id()), 53a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) new_title(new_title), 54a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) location_type(NOT_IN_METADATA) { 55a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 56a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Parameters supplied or calculated from operation arguments. 57a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const FileOperationCallback callback; 58a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const std::string resource_id; 59a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const std::string parent_resource_id; 60a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const std::string parent_local_id; 61a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const std::string new_title; 62a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 63a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Values computed during operation. 64a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) JsonGdocLocationType location_type; // types where the gdoc file is located. 65a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) std::string local_id; // the local_id of the file (if exists in metadata.) 66a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::FilePath changed_path; 67a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}; 68a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)FileError TryToCopyLocally(internal::ResourceMetadata* metadata, 725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) internal::FileCache* cache, 735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) CopyOperation::CopyParams* params, 745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::vector<std::string>* updated_local_ids, 755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool* directory_changed, 765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool* should_copy_on_server) { 775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) FileError error = metadata->GetResourceEntryByPath(params->src_file_path, 785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ¶ms->src_entry); 79424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (error != FILE_ERROR_OK) 80424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return error; 81424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) error = metadata->GetResourceEntryByPath(params->dest_file_path.DirName(), 835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ¶ms->parent_entry); 84424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (error != FILE_ERROR_OK) 85424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return error; 86424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!params->parent_entry.file_info().is_directory()) 88424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return FILE_ERROR_NOT_A_DIRECTORY; 89424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 90424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Drive File System doesn't support recursive copy. 915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (params->src_entry.file_info().is_directory()) 92d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return FILE_ERROR_NOT_A_FILE; 93424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Check destination. 955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ResourceEntry dest_entry; 965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) error = metadata->GetResourceEntryByPath(params->dest_file_path, &dest_entry); 975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) switch (error) { 985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) case FILE_ERROR_OK: 995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // File API spec says it is an error to try to "copy a file to a path 1005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // occupied by a directory". 1015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (dest_entry.file_info().is_directory()) 1025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return FILE_ERROR_INVALID_OPERATION; 1035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Move the existing entry to the trash. 1055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) dest_entry.set_parent_local_id(util::kDriveTrashDirLocalId); 1065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) error = metadata->RefreshEntry(dest_entry); 1075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (error != FILE_ERROR_OK) 1085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return error; 1095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) updated_local_ids->push_back(dest_entry.local_id()); 1105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) *directory_changed = true; 1115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) break; 1125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) case FILE_ERROR_NOT_FOUND: 1135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) break; 1145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) default: 1155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return error; 1165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // If the cache file is not present and the entry exists on the server, 1195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // server side copy should be used. 120cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (!params->src_entry.file_specific_info().cache_state().is_present() && 121cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) !params->src_entry.resource_id().empty()) { 1225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) *should_copy_on_server = true; 1235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return FILE_ERROR_OK; 1245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Copy locally. 1275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ResourceEntry entry; 1285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const int64 now = base::Time::Now().ToInternalValue(); 1295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) entry.set_title(params->dest_file_path.BaseName().AsUTF8Unsafe()); 1305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) entry.set_parent_local_id(params->parent_entry.local_id()); 1315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) entry.mutable_file_specific_info()->set_content_mime_type( 1325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) params->src_entry.file_specific_info().content_mime_type()); 1335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) entry.set_metadata_edit_state(ResourceEntry::DIRTY); 1340529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch entry.set_modification_date(base::Time::Now().ToInternalValue()); 1355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) entry.mutable_file_info()->set_last_modified( 1365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) params->preserve_last_modified ? 1375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) params->src_entry.file_info().last_modified() : now); 1385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) entry.mutable_file_info()->set_last_accessed(now); 1395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::string local_id; 1415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) error = metadata->AddEntry(entry, &local_id); 1425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (error != FILE_ERROR_OK) 1435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return error; 1445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) updated_local_ids->push_back(local_id); 1455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) *directory_changed = true; 146424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 147cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (!params->src_entry.file_specific_info().cache_state().is_present()) { 1485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(params->src_entry.resource_id().empty()); 1495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Locally created empty file may have no cache file. 1505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return FILE_ERROR_OK; 1515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::FilePath cache_file_path; 1545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) error = cache->GetFile(params->src_entry.local_id(), &cache_file_path); 1555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (error != FILE_ERROR_OK) 1565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return error; 1575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return cache->Store(local_id, std::string(), cache_file_path, 1595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) internal::FileCache::FILE_OPERATION_COPY); 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 162a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Stores the entry returned from the server and returns its path. 163a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)FileError UpdateLocalStateForServerSideOperation( 164424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) internal::ResourceMetadata* metadata, 165f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) scoped_ptr<google_apis::FileResource> file_resource, 166116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ResourceEntry* entry, 167424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) base::FilePath* file_path) { 168f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) DCHECK(file_resource); 16958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 17058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) std::string parent_resource_id; 171116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (!ConvertFileResourceToResourceEntry( 172116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch *file_resource, entry, &parent_resource_id) || 1735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) parent_resource_id.empty()) 17458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return FILE_ERROR_NOT_A_FILE; 17558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 17658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) std::string parent_local_id; 17758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) FileError error = metadata->GetIdByResourceId(parent_resource_id, 17858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) &parent_local_id); 17958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (error != FILE_ERROR_OK) 18058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return error; 181116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch entry->set_parent_local_id(parent_local_id); 18258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 183424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) std::string local_id; 184116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch error = metadata->AddEntry(*entry, &local_id); 185424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Depending on timing, the metadata may have inserted via change list 186424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // already. So, FILE_ERROR_EXISTS is not an error. 187424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (error == FILE_ERROR_EXISTS) 188116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch error = metadata->GetIdByResourceId(entry->resource_id(), &local_id); 189424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 190cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (error != FILE_ERROR_OK) 191cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return error; 192424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 193cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return metadata->GetFilePath(local_id, file_path); 194424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 195424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 1963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// Stores the file at |local_file_path| to the cache as a content of entry at 1973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// |remote_dest_path|, and marks it dirty. 1983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)FileError UpdateLocalStateForScheduleTransfer( 1993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) internal::ResourceMetadata* metadata, 2003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) internal::FileCache* cache, 2013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const base::FilePath& local_src_path, 2023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const base::FilePath& remote_dest_path, 203116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ResourceEntry* entry, 20458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) std::string* local_id) { 20558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) FileError error = metadata->GetIdByPath(remote_dest_path, local_id); 20658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (error != FILE_ERROR_OK) 20758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return error; 20858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 209116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch error = metadata->GetResourceEntryById(*local_id, entry); 2103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (error != FILE_ERROR_OK) 2113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return error; 2123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 2135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return cache->Store(*local_id, std::string(), local_src_path, 2145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) internal::FileCache::FILE_OPERATION_COPY); 2157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 2167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 217ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// Gets the file size of the |local_path|, and the ResourceEntry for the parent 218ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// of |remote_path| to prepare the necessary information for transfer. 219ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben MurdochFileError PrepareTransferFileFromLocalToRemote( 220ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch internal::ResourceMetadata* metadata, 221424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const base::FilePath& local_src_path, 222424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const base::FilePath& remote_dest_path, 22358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) std::string* gdoc_resource_id, 224a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ResourceEntry* parent_entry) { 225424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) FileError error = metadata->GetResourceEntryByPath( 226a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) remote_dest_path.DirName(), parent_entry); 227424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (error != FILE_ERROR_OK) 228424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return error; 229ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 230424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // The destination's parent must be a directory. 231a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!parent_entry->file_info().is_directory()) 232424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return FILE_ERROR_NOT_A_DIRECTORY; 233ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 234424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Try to parse GDoc File and extract the resource id, if necessary. 235424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Failing isn't problem. It'd be handled as a regular file, then. 2365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (util::HasHostedDocumentExtension(local_src_path)) 23758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) *gdoc_resource_id = util::ReadResourceIdFromGDocFile(local_src_path); 238a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return FILE_ERROR_OK; 239a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 240a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 241a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Performs local work before server-side work for transferring JSON-represented 242a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// gdoc files. 243a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)FileError LocalWorkForTransferJsonGdocFile( 244a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) internal::ResourceMetadata* metadata, 245a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) CopyOperation::TransferJsonGdocParams* params) { 246a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) std::string local_id; 247a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) FileError error = metadata->GetIdByResourceId(params->resource_id, &local_id); 248a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (error != FILE_ERROR_OK) { 249a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) params->location_type = NOT_IN_METADATA; 250a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return error == FILE_ERROR_NOT_FOUND ? FILE_ERROR_OK : error; 251a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 252a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 253a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ResourceEntry entry; 254a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) error = metadata->GetResourceEntryById(local_id, &entry); 255a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (error != FILE_ERROR_OK) 256a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return error; 257a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) params->local_id = entry.local_id(); 258a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 259a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (entry.parent_local_id() == util::kDriveOtherDirLocalId) { 260a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) params->location_type = IS_ORPHAN; 261a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) entry.set_title(params->new_title); 262a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) entry.set_parent_local_id(params->parent_local_id); 263a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) entry.set_metadata_edit_state(ResourceEntry::DIRTY); 2640529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch entry.set_modification_date(base::Time::Now().ToInternalValue()); 265a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) error = metadata->RefreshEntry(entry); 266cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (error != FILE_ERROR_OK) 267cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return error; 268cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return metadata->GetFilePath(local_id, ¶ms->changed_path); 26958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 270424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 271a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) params->location_type = HAS_PARENT; 272424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return FILE_ERROR_OK; 2733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 2743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 27790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)CopyOperation::CopyOperation(base::SequencedTaskRunner* blocking_task_runner, 2785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) OperationDelegate* delegate, 27990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) JobScheduler* scheduler, 28090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) internal::ResourceMetadata* metadata, 2815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) internal::FileCache* cache) 28290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) : blocking_task_runner_(blocking_task_runner), 2835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) delegate_(delegate), 28490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scheduler_(scheduler), 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) metadata_(metadata), 286c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) cache_(cache), 28790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) create_file_operation_(new CreateFileOperation(blocking_task_runner, 2885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) delegate, 2895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) metadata)), 290c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) weak_ptr_factory_(this) { 2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CopyOperation::~CopyOperation() { 2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void CopyOperation::Copy(const base::FilePath& src_file_path, 2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::FilePath& dest_file_path, 30068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) bool preserve_last_modified, 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const FileOperationCallback& callback) { 302424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!callback.is_null()); 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) CopyParams* params = new CopyParams; 3065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) params->src_file_path = src_file_path; 3075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) params->dest_file_path = dest_file_path; 3085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) params->preserve_last_modified = preserve_last_modified; 3095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) params->callback = callback; 31068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 3115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::vector<std::string>* updated_local_ids = new std::vector<std::string>; 3125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool* directory_changed = new bool(false); 3135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool* should_copy_on_server = new bool(false); 314424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) base::PostTaskAndReplyWithResult( 315424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) blocking_task_runner_.get(), 316424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) FROM_HERE, 3175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::Bind(&TryToCopyLocally, metadata_, cache_, params, 3185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) updated_local_ids, directory_changed, should_copy_on_server), 3195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::Bind(&CopyOperation::CopyAfterTryToCopyLocally, 3205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) weak_ptr_factory_.GetWeakPtr(), base::Owned(params), 3215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::Owned(updated_local_ids), base::Owned(directory_changed), 3225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::Owned(should_copy_on_server))); 323424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 324424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 3255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void CopyOperation::CopyAfterTryToCopyLocally( 3265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const CopyParams* params, 3275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const std::vector<std::string>* updated_local_ids, 3285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const bool* directory_changed, 3295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const bool* should_copy_on_server, 3305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) FileError error) { 331424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 3325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(!params->callback.is_null()); 333424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 3345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (size_t i = 0; i < updated_local_ids->size(); ++i) 3355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) delegate_->OnEntryUpdatedByOperation((*updated_local_ids)[i]); 3365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 337116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (*directory_changed) { 338116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch FileChange changed_file; 339116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DCHECK(!params->src_entry.file_info().is_directory()); 340116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch changed_file.Update(params->dest_file_path, 341116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch FileChange::FILE_TYPE_FILE, 342116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch FileChange::ADD_OR_UPDATE); 3435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) delegate_->OnFileChangedByOperation(changed_file); 344116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 3455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (error != FILE_ERROR_OK || !*should_copy_on_server) { 3475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) params->callback.Run(error); 348424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return; 349424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 350424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 3515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (params->parent_entry.resource_id().empty()) { 3525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // Parent entry may be being synced. 3535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const bool waiting = delegate_->WaitForSyncComplete( 3545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) params->parent_entry.local_id(), 3555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base::Bind(&CopyOperation::CopyAfterParentSync, 3565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) weak_ptr_factory_.GetWeakPtr(), *params)); 3575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (!waiting) 3585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) params->callback.Run(FILE_ERROR_NOT_FOUND); 3595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } else { 3605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) CopyAfterGetParentResourceId(*params, ¶ms->parent_entry, FILE_ERROR_OK); 3615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 3625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 3635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 3645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void CopyOperation::CopyAfterParentSync(const CopyParams& params, 3655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) FileError error) { 3665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 3675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DCHECK(!params.callback.is_null()); 3685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 3695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (error != FILE_ERROR_OK) { 3705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) params.callback.Run(error); 3715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return; 3725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 3735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 3745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ResourceEntry* parent = new ResourceEntry; 3755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base::PostTaskAndReplyWithResult( 3761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci blocking_task_runner_.get(), 3775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) FROM_HERE, 3785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base::Bind(&internal::ResourceMetadata::GetResourceEntryById, 3795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base::Unretained(metadata_), 3801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci params.parent_entry.local_id(), 3811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci parent), 3825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base::Bind(&CopyOperation::CopyAfterGetParentResourceId, 3831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci weak_ptr_factory_.GetWeakPtr(), 3841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci params, 3851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::Owned(parent))); 3865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 3875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 3885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void CopyOperation::CopyAfterGetParentResourceId(const CopyParams& params, 3895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const ResourceEntry* parent, 3905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) FileError error) { 3915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 3925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DCHECK(!params.callback.is_null()); 3935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 3945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (error != FILE_ERROR_OK) { 3955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) params.callback.Run(error); 3965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return; 3975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 3985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 3995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base::FilePath new_title = params.dest_file_path.BaseName(); 4005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (params.src_entry.file_specific_info().is_hosted_document()) { 401a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Drop the document extension, which should not be in the title. 402a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // TODO(yoshiki): Remove this code with crbug.com/223304. 403a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) new_title = new_title.RemoveExtension(); 404424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 405424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 406a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::Time last_modified = 4075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) params.preserve_last_modified ? 4085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::Time::FromInternalValue( 4095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) params.src_entry.file_info().last_modified()) : base::Time(); 410424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 411a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) CopyResourceOnServer( 4125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) params.src_entry.resource_id(), parent->resource_id(), 4135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) new_title.AsUTF8Unsafe(), last_modified, params.callback); 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CopyOperation::TransferFileFromLocalToRemote( 417424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const base::FilePath& local_src_path, 418424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const base::FilePath& remote_dest_path, 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const FileOperationCallback& callback) { 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!callback.is_null()); 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 42358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) std::string* gdoc_resource_id = new std::string; 424a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ResourceEntry* parent_entry = new ResourceEntry; 425ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch base::PostTaskAndReplyWithResult( 426ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch blocking_task_runner_.get(), 427ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch FROM_HERE, 428424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) base::Bind( 429424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) &PrepareTransferFileFromLocalToRemote, 43058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) metadata_, local_src_path, remote_dest_path, 431a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) gdoc_resource_id, parent_entry), 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind( 433ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch &CopyOperation::TransferFileFromLocalToRemoteAfterPrepare, 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) weak_ptr_factory_.GetWeakPtr(), 435424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) local_src_path, remote_dest_path, callback, 436a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::Owned(gdoc_resource_id), base::Owned(parent_entry))); 437424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 438424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 439424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)void CopyOperation::TransferFileFromLocalToRemoteAfterPrepare( 440424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const base::FilePath& local_src_path, 441424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const base::FilePath& remote_dest_path, 442424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const FileOperationCallback& callback, 44358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) std::string* gdoc_resource_id, 444a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ResourceEntry* parent_entry, 445424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) FileError error) { 446424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 447424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) DCHECK(!callback.is_null()); 448424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 449424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (error != FILE_ERROR_OK) { 450424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) callback.Run(error); 451424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return; 452424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 453424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 454424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // For regular files, schedule the transfer. 45558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (gdoc_resource_id->empty()) { 456424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ScheduleTransferRegularFile(local_src_path, remote_dest_path, callback); 457424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return; 458424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 459424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 460424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // GDoc file may contain a resource ID in the old format. 461424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const std::string canonicalized_resource_id = 4625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) util::CanonicalizeResourceId(*gdoc_resource_id); 463424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 464a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Drop the document extension, which should not be in the title. 465a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // TODO(yoshiki): Remove this code with crbug.com/223304. 466a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const std::string new_title = 467a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) remote_dest_path.BaseName().RemoveExtension().AsUTF8Unsafe(); 468a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 469a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // This is uploading a JSON file representing a hosted document. 470a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TransferJsonGdocParams* params = new TransferJsonGdocParams( 471a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) callback, canonicalized_resource_id, *parent_entry, new_title); 472a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::PostTaskAndReplyWithResult( 473a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) blocking_task_runner_.get(), 474a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) FROM_HERE, 475a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::Bind(&LocalWorkForTransferJsonGdocFile, metadata_, params), 476a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::Bind(&CopyOperation::TransferJsonGdocFileAfterLocalWork, 477a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) weak_ptr_factory_.GetWeakPtr(), base::Owned(params))); 478a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 479a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 480a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void CopyOperation::TransferJsonGdocFileAfterLocalWork( 481a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TransferJsonGdocParams* params, 482a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) FileError error) { 483a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 484a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 485a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (error != FILE_ERROR_OK) { 486a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) params->callback.Run(error); 487a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return; 488a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 489a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 490a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) switch (params->location_type) { 491a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // When |resource_id| is found in the local metadata and it has a specific 492a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // parent folder, we assume the user's intention is to copy the document and 493a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // thus perform the server-side copy operation. 494a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) case HAS_PARENT: 495a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) CopyResourceOnServer(params->resource_id, 496a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) params->parent_resource_id, 497a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) params->new_title, 498a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::Time(), 499a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) params->callback); 500a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) break; 501a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // When |resource_id| has no parent, we just set the new destination folder 502a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // as the parent, for sharing the document between the original source. 503a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // This reparenting is already done in LocalWorkForTransferJsonGdocFile(). 504116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch case IS_ORPHAN: { 505a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK(!params->changed_path.empty()); 5065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) delegate_->OnEntryUpdatedByOperation(params->local_id); 507116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 508116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch FileChange changed_file; 509116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch changed_file.Update( 510116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch params->changed_path, 511116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch FileChange::FILE_TYPE_FILE, // This must be a hosted document. 512116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch FileChange::ADD_OR_UPDATE); 5135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) delegate_->OnFileChangedByOperation(changed_file); 514a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) params->callback.Run(error); 515a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) break; 516116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 517a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // When the |resource_id| is not in the local metadata, assume it to be a 518a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // document just now shared on the server but not synced locally. 519a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Same as the IS_ORPHAN case, we want to deal the case by setting parent, 520a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // but this time we need to resort to server side operation. 521a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) case NOT_IN_METADATA: 522a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) scheduler_->UpdateResource( 523a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) params->resource_id, 524a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) params->parent_resource_id, 525a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) params->new_title, 526a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::Time(), 527a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::Time(), 528a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ClientContext(USER_INITIATED), 529a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::Bind(&CopyOperation::UpdateAfterServerSideOperation, 530a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) weak_ptr_factory_.GetWeakPtr(), 531a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) params->callback)); 532a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) break; 533a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 534424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 535424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 536424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)void CopyOperation::CopyResourceOnServer( 537424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const std::string& resource_id, 538424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const std::string& parent_resource_id, 539424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const std::string& new_title, 54068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const base::Time& last_modified, 541424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const FileOperationCallback& callback) { 542424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 543424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) DCHECK(!callback.is_null()); 544424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 545424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) scheduler_->CopyResource( 54668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) resource_id, parent_resource_id, new_title, last_modified, 547a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::Bind(&CopyOperation::UpdateAfterServerSideOperation, 548424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) weak_ptr_factory_.GetWeakPtr(), 549424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) callback)); 550424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 551424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 552a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void CopyOperation::UpdateAfterServerSideOperation( 553424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const FileOperationCallback& callback, 554424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) google_apis::GDataErrorCode status, 555f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) scoped_ptr<google_apis::FileResource> entry) { 556424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 557424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) DCHECK(!callback.is_null()); 558424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 559424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) FileError error = GDataToFileError(status); 560424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (error != FILE_ERROR_OK) { 561424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) callback.Run(error); 562424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return; 563424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 564424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 565116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ResourceEntry* resource_entry = new ResourceEntry; 566116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 567424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // The copy on the server side is completed successfully. Update the local 568424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // metadata. 569424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) base::FilePath* file_path = new base::FilePath; 570424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) base::PostTaskAndReplyWithResult( 571424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) blocking_task_runner_.get(), 572424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) FROM_HERE, 573a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::Bind(&UpdateLocalStateForServerSideOperation, 574116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch metadata_, 575116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch base::Passed(&entry), 576116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch resource_entry, 577116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch file_path), 578a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::Bind(&CopyOperation::UpdateAfterLocalStateUpdate, 579424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) weak_ptr_factory_.GetWeakPtr(), 580116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch callback, 581116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch base::Owned(file_path), 582116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch base::Owned(resource_entry))); 583424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 584424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 585a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void CopyOperation::UpdateAfterLocalStateUpdate( 586424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const FileOperationCallback& callback, 587424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) base::FilePath* file_path, 588116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const ResourceEntry* entry, 589424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) FileError error) { 590424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 591424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) DCHECK(!callback.is_null()); 592424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 593116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (error == FILE_ERROR_OK) { 594116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch FileChange changed_file; 595116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch changed_file.Update(*file_path, *entry, FileChange::ADD_OR_UPDATE); 5965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) delegate_->OnFileChangedByOperation(changed_file); 597116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 598424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) callback.Run(error); 5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 601c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void CopyOperation::ScheduleTransferRegularFile( 6023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const base::FilePath& local_src_path, 6033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const base::FilePath& remote_dest_path, 6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const FileOperationCallback& callback) { 6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 6062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!callback.is_null()); 6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) create_file_operation_->CreateFile( 6093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) remote_dest_path, 6105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) false, // Not exclusive (OK even if a file already exists). 6113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) std::string(), // no specific mime type; CreateFile should guess it. 6123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::Bind(&CopyOperation::ScheduleTransferRegularFileAfterCreate, 6133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) weak_ptr_factory_.GetWeakPtr(), 6143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) local_src_path, remote_dest_path, callback)); 6153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 6163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 6173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void CopyOperation::ScheduleTransferRegularFileAfterCreate( 6183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const base::FilePath& local_src_path, 6193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const base::FilePath& remote_dest_path, 6203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const FileOperationCallback& callback, 6213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) FileError error) { 6223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 6233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) DCHECK(!callback.is_null()); 6243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 6253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (error != FILE_ERROR_OK) { 6263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) callback.Run(error); 6273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return; 6283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 6293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 63058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) std::string* local_id = new std::string; 631116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ResourceEntry* entry = new ResourceEntry; 6327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) base::PostTaskAndReplyWithResult( 6337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) blocking_task_runner_.get(), 6347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) FROM_HERE, 635116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch base::Bind(&UpdateLocalStateForScheduleTransfer, 636116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch metadata_, 637116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch cache_, 638116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch local_src_path, 639116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch remote_dest_path, 640116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch entry, 641116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch local_id), 6423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::Bind( 6433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) &CopyOperation::ScheduleTransferRegularFileAfterUpdateLocalState, 644116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch weak_ptr_factory_.GetWeakPtr(), 645116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch callback, 646116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch remote_dest_path, 647116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch base::Owned(entry), 6485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::Owned(local_id))); 6497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 6507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 6513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void CopyOperation::ScheduleTransferRegularFileAfterUpdateLocalState( 6527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const FileOperationCallback& callback, 6535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const base::FilePath& remote_dest_path, 654116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const ResourceEntry* entry, 65558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) std::string* local_id, 6567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) FileError error) { 6573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 6583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) DCHECK(!callback.is_null()); 6593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 6605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (error == FILE_ERROR_OK) { 661116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch FileChange changed_file; 662116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch changed_file.Update(remote_dest_path, *entry, FileChange::ADD_OR_UPDATE); 6635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) delegate_->OnFileChangedByOperation(changed_file); 6645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) delegate_->OnEntryUpdatedByOperation(*local_id); 6655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 6667d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) callback.Run(error); 6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace file_system 6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace drive 671