- add sources.
[platform/framework/web/crosswalk.git] / src / chrome / browser / chromeos / drive / file_system / touch_operation.cc
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/browser/chromeos/drive/file_system/touch_operation.h"
6
7 #include "base/bind.h"
8 #include "base/files/file_path.h"
9 #include "base/sequenced_task_runner.h"
10 #include "base/time/time.h"
11 #include "chrome/browser/chromeos/drive/file_errors.h"
12 #include "chrome/browser/chromeos/drive/file_system/operation_observer.h"
13 #include "chrome/browser/chromeos/drive/file_system_util.h"
14 #include "chrome/browser/chromeos/drive/job_scheduler.h"
15 #include "chrome/browser/chromeos/drive/resource_entry_conversion.h"
16 #include "chrome/browser/chromeos/drive/resource_metadata.h"
17 #include "content/public/browser/browser_thread.h"
18
19 using content::BrowserThread;
20
21 namespace drive {
22 namespace file_system {
23
24 namespace {
25
26 // Returns ResourceEntry and the local ID of the entry at the given path.
27 FileError GetResourceEntryAndIdByPath(internal::ResourceMetadata* metadata,
28                                       const base::FilePath& file_path,
29                                       std::string* local_id,
30                                       ResourceEntry* entry) {
31   FileError error = metadata->GetIdByPath(file_path, local_id);
32   if (error != FILE_ERROR_OK)
33     return error;
34   return metadata->GetResourceEntryById(*local_id, entry);
35 }
36
37 // Refreshes the entry specified by |local_id| with the contents of
38 // |resource_entry|.
39 FileError RefreshEntry(internal::ResourceMetadata* metadata,
40                        const std::string& local_id,
41                        scoped_ptr<google_apis::ResourceEntry> resource_entry,
42                        base::FilePath* file_path) {
43   DCHECK(resource_entry);
44
45   ResourceEntry entry;
46   std::string parent_resource_id;
47   if (!ConvertToResourceEntry(*resource_entry, &entry, &parent_resource_id))
48     return FILE_ERROR_NOT_A_FILE;
49
50   std::string parent_local_id;
51   FileError error = metadata->GetIdByResourceId(parent_resource_id,
52                                                 &parent_local_id);
53   if (error != FILE_ERROR_OK)
54     return error;
55
56   entry.set_local_id(local_id);
57   entry.set_parent_local_id(parent_local_id);
58
59   error = metadata->RefreshEntry(entry);
60   if (error != FILE_ERROR_OK)
61     return error;
62
63   *file_path = metadata->GetFilePath(local_id);
64   return file_path->empty() ? FILE_ERROR_FAILED : FILE_ERROR_OK;
65 }
66
67 }  // namespace
68
69 TouchOperation::TouchOperation(base::SequencedTaskRunner* blocking_task_runner,
70                                OperationObserver* observer,
71                                JobScheduler* scheduler,
72                                internal::ResourceMetadata* metadata)
73     : blocking_task_runner_(blocking_task_runner),
74       observer_(observer),
75       scheduler_(scheduler),
76       metadata_(metadata),
77       weak_ptr_factory_(this) {
78 }
79
80 TouchOperation::~TouchOperation() {
81 }
82
83 void TouchOperation::TouchFile(const base::FilePath& file_path,
84                                const base::Time& last_access_time,
85                                const base::Time& last_modified_time,
86                                const FileOperationCallback& callback) {
87   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
88   DCHECK(!callback.is_null());
89
90   ResourceEntry* entry = new ResourceEntry;
91   std::string* local_id = new std::string;
92   base::PostTaskAndReplyWithResult(
93       blocking_task_runner_.get(),
94       FROM_HERE,
95       base::Bind(&GetResourceEntryAndIdByPath,
96                  base::Unretained(metadata_),
97                  file_path,
98                  local_id,
99                  entry),
100       base::Bind(&TouchOperation::TouchFileAfterGetResourceEntry,
101                  weak_ptr_factory_.GetWeakPtr(),
102                  last_access_time,
103                  last_modified_time,
104                  callback,
105                  base::Owned(local_id),
106                  base::Owned(entry)));
107 }
108
109 void TouchOperation::TouchFileAfterGetResourceEntry(
110     const base::Time& last_access_time,
111     const base::Time& last_modified_time,
112     const FileOperationCallback& callback,
113     std::string* local_id,
114     ResourceEntry* entry,
115     FileError error) {
116   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
117   DCHECK(!callback.is_null());
118   DCHECK(entry);
119
120   if (error != FILE_ERROR_OK) {
121     callback.Run(error);
122     return;
123   }
124
125   // Note: |last_modified_time| is mapped to modifiedDate, |last_access_time|
126   // is mapped to lastViewedByMeDate. See also ConvertToResourceEntry().
127   scheduler_->TouchResource(
128       entry->resource_id(), last_modified_time, last_access_time,
129       base::Bind(&TouchOperation::TouchFileAfterServerTimeStampUpdated,
130                  weak_ptr_factory_.GetWeakPtr(),
131                  *local_id, callback));
132 }
133
134 void TouchOperation::TouchFileAfterServerTimeStampUpdated(
135     const std::string& local_id,
136     const FileOperationCallback& callback,
137     google_apis::GDataErrorCode gdata_error,
138     scoped_ptr<google_apis::ResourceEntry> resource_entry) {
139   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
140   DCHECK(!callback.is_null());
141
142   FileError error = GDataToFileError(gdata_error);
143   if (error != FILE_ERROR_OK) {
144     callback.Run(error);
145     return;
146   }
147
148   base::FilePath* file_path = new base::FilePath;
149   base::PostTaskAndReplyWithResult(
150       blocking_task_runner_.get(),
151       FROM_HERE,
152       base::Bind(&RefreshEntry,
153                  base::Unretained(metadata_),
154                  local_id,
155                  base::Passed(&resource_entry),
156                  file_path),
157       base::Bind(&TouchOperation::TouchFileAfterRefreshMetadata,
158                  weak_ptr_factory_.GetWeakPtr(),
159                  base::Owned(file_path),
160                  callback));
161 }
162
163 void TouchOperation::TouchFileAfterRefreshMetadata(
164     const base::FilePath* file_path,
165     const FileOperationCallback& callback,
166     FileError error) {
167   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
168   DCHECK(!callback.is_null());
169
170   if (error == FILE_ERROR_OK)
171     observer_->OnDirectoryChangedByOperation(file_path->DirName());
172
173   callback.Run(error);
174 }
175
176 }  // namespace file_system
177 }  // namespace drive