1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/chromeos/drive/file_system/move_operation.h"
7 #include "base/sequenced_task_runner.h"
8 #include "chrome/browser/chromeos/drive/drive.pb.h"
9 #include "chrome/browser/chromeos/drive/file_system/operation_observer.h"
10 #include "chrome/browser/chromeos/drive/resource_metadata.h"
11 #include "content/public/browser/browser_thread.h"
13 using content::BrowserThread
;
16 namespace file_system
{
19 // Looks up ResourceEntry for source entry and the destination directory.
20 FileError
UpdateLocalState(internal::ResourceMetadata
* metadata
,
21 const base::FilePath
& src_path
,
22 const base::FilePath
& dest_path
,
23 bool preserve_last_modified
,
24 std::set
<base::FilePath
>* changed_directories
,
25 std::string
* local_id
) {
27 FileError error
= metadata
->GetResourceEntryByPath(src_path
, &entry
);
28 if (error
!= FILE_ERROR_OK
)
30 *local_id
= entry
.local_id();
32 ResourceEntry parent_entry
;
33 error
= metadata
->GetResourceEntryByPath(dest_path
.DirName(), &parent_entry
);
34 if (error
!= FILE_ERROR_OK
)
37 // The parent must be a directory.
38 if (!parent_entry
.file_info().is_directory())
39 return FILE_ERROR_NOT_A_DIRECTORY
;
41 // Strip the extension for a hosted document if necessary.
42 const std::string new_extension
=
43 base::FilePath(dest_path
.Extension()).AsUTF8Unsafe();
44 const bool has_hosted_document_extension
=
45 entry
.has_file_specific_info() &&
46 entry
.file_specific_info().is_hosted_document() &&
47 new_extension
== entry
.file_specific_info().document_extension();
48 const std::string new_title
=
49 has_hosted_document_extension
?
50 dest_path
.BaseName().RemoveExtension().AsUTF8Unsafe() :
51 dest_path
.BaseName().AsUTF8Unsafe();
53 // Update last_modified.
54 if (!preserve_last_modified
) {
55 entry
.mutable_file_info()->set_last_modified(
56 base::Time::Now().ToInternalValue());
59 entry
.set_title(new_title
);
60 entry
.set_parent_local_id(parent_entry
.local_id());
61 entry
.set_metadata_edit_state(ResourceEntry::DIRTY
);
62 error
= metadata
->RefreshEntry(entry
);
63 if (error
!= FILE_ERROR_OK
)
66 changed_directories
->insert(src_path
.DirName());
67 changed_directories
->insert(dest_path
.DirName());
73 MoveOperation::MoveOperation(base::SequencedTaskRunner
* blocking_task_runner
,
74 OperationObserver
* observer
,
75 internal::ResourceMetadata
* metadata
)
76 : blocking_task_runner_(blocking_task_runner
),
79 weak_ptr_factory_(this) {
80 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
83 MoveOperation::~MoveOperation() {
84 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
87 void MoveOperation::Move(const base::FilePath
& src_file_path
,
88 const base::FilePath
& dest_file_path
,
89 bool preserve_last_modified
,
90 const FileOperationCallback
& callback
) {
91 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
92 DCHECK(!callback
.is_null());
94 std::set
<base::FilePath
>* changed_directories
= new std::set
<base::FilePath
>;
95 std::string
* local_id
= new std::string
;
96 base::PostTaskAndReplyWithResult(
97 blocking_task_runner_
.get(),
99 base::Bind(&UpdateLocalState
,
103 preserve_last_modified
,
106 base::Bind(&MoveOperation::MoveAfterUpdateLocalState
,
107 weak_ptr_factory_
.GetWeakPtr(),
109 base::Owned(changed_directories
),
110 base::Owned(local_id
)));
113 void MoveOperation::MoveAfterUpdateLocalState(
114 const FileOperationCallback
& callback
,
115 const std::set
<base::FilePath
>* changed_directories
,
116 const std::string
* local_id
,
118 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
119 if (error
== FILE_ERROR_OK
) {
120 // Notify the change of directory.
121 for (std::set
<base::FilePath
>::const_iterator it
=
122 changed_directories
->begin();
123 it
!= changed_directories
->end(); ++it
)
124 observer_
->OnDirectoryChangedByOperation(*it
);
126 observer_
->OnEntryUpdatedByOperation(*local_id
);
131 } // namespace file_system