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/resource_metadata.h"
14#include "content/public/browser/browser_thread.h"
15
16using content::BrowserThread;
17
18namespace drive {
19namespace file_system {
20
21namespace {
22
23// Updates the timestamps of the entry specified by |file_path|.
24FileError UpdateLocalState(internal::ResourceMetadata* metadata,
25                           const base::FilePath& file_path,
26                           const base::Time& last_access_time,
27                           const base::Time& last_modified_time,
28                       std::string* local_id) {
29  ResourceEntry entry;
30  FileError error = metadata->GetResourceEntryByPath(file_path, &entry);
31  if (error != FILE_ERROR_OK)
32    return error;
33  *local_id = entry.local_id();
34
35  PlatformFileInfoProto* file_info = entry.mutable_file_info();
36  if (!last_access_time.is_null())
37    file_info->set_last_accessed(last_access_time.ToInternalValue());
38  if (!last_modified_time.is_null())
39    file_info->set_last_modified(last_modified_time.ToInternalValue());
40  entry.set_metadata_edit_state(ResourceEntry::DIRTY);
41  return metadata->RefreshEntry(entry);
42}
43
44}  // namespace
45
46TouchOperation::TouchOperation(base::SequencedTaskRunner* blocking_task_runner,
47                               OperationObserver* observer,
48                               internal::ResourceMetadata* metadata)
49    : blocking_task_runner_(blocking_task_runner),
50      observer_(observer),
51      metadata_(metadata),
52      weak_ptr_factory_(this) {
53}
54
55TouchOperation::~TouchOperation() {
56}
57
58void TouchOperation::TouchFile(const base::FilePath& file_path,
59                               const base::Time& last_access_time,
60                               const base::Time& last_modified_time,
61                               const FileOperationCallback& callback) {
62  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
63  DCHECK(!callback.is_null());
64
65  std::string* local_id = new std::string;
66  base::PostTaskAndReplyWithResult(
67      blocking_task_runner_.get(),
68      FROM_HERE,
69      base::Bind(&UpdateLocalState,
70                 metadata_,
71                 file_path,
72                 last_access_time,
73                 last_modified_time,
74                 local_id),
75      base::Bind(&TouchOperation::TouchFileAfterUpdateLocalState,
76                 weak_ptr_factory_.GetWeakPtr(),
77                 file_path,
78                 callback,
79                 base::Owned(local_id)));
80}
81
82void TouchOperation::TouchFileAfterUpdateLocalState(
83    const base::FilePath& file_path,
84    const FileOperationCallback& callback,
85    const std::string* local_id,
86    FileError error) {
87  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
88  DCHECK(!callback.is_null());
89
90  if (error == FILE_ERROR_OK) {
91    observer_->OnDirectoryChangedByOperation(file_path.DirName());
92    observer_->OnEntryUpdatedByOperation(*local_id);
93  }
94  callback.Run(error);
95}
96
97}  // namespace file_system
98}  // namespace drive
99