Home | History | Annotate | Download | only in file_system
      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.
      4 
      5 #include "chrome/browser/chromeos/drive/file_system/remove_operation.h"
      6 
      7 #include "base/sequenced_task_runner.h"
      8 #include "chrome/browser/chromeos/drive/drive.pb.h"
      9 #include "chrome/browser/chromeos/drive/file_cache.h"
     10 #include "chrome/browser/chromeos/drive/file_change.h"
     11 #include "chrome/browser/chromeos/drive/file_system/operation_delegate.h"
     12 #include "chrome/browser/chromeos/drive/file_system_util.h"
     13 #include "chrome/browser/chromeos/drive/resource_metadata.h"
     14 #include "content/public/browser/browser_thread.h"
     15 
     16 using content::BrowserThread;
     17 
     18 namespace drive {
     19 namespace file_system {
     20 
     21 namespace {
     22 
     23 // Removes cache file and moves the metadata entry to the trash.
     24 FileError UpdateLocalState(internal::ResourceMetadata* metadata,
     25                            internal::FileCache* cache,
     26                            const base::FilePath& path,
     27                            bool is_recursive,
     28                            std::string* local_id,
     29                            ResourceEntry* entry,
     30                            base::FilePath* changed_path) {
     31   FileError error = metadata->GetIdByPath(path, local_id);
     32   if (error != FILE_ERROR_OK)
     33     return error;
     34 
     35   error = metadata->GetResourceEntryById(*local_id, entry);
     36   if (error != FILE_ERROR_OK)
     37     return error;
     38 
     39   if (entry->file_info().is_directory() && !is_recursive) {
     40     // Check emptiness of the directory.
     41     ResourceEntryVector entries;
     42     error = metadata->ReadDirectoryByPath(path, &entries);
     43     if (error != FILE_ERROR_OK)
     44       return error;
     45     if (!entries.empty())
     46       return FILE_ERROR_NOT_EMPTY;
     47   }
     48 
     49   error = cache->Remove(*local_id);
     50   if (error != FILE_ERROR_OK)
     51     return error;
     52 
     53   *changed_path = path;
     54 
     55   // Move to the trash.
     56   entry->set_parent_local_id(util::kDriveTrashDirLocalId);
     57   return metadata->RefreshEntry(*entry);
     58 }
     59 
     60 }  // namespace
     61 
     62 RemoveOperation::RemoveOperation(
     63     base::SequencedTaskRunner* blocking_task_runner,
     64     OperationDelegate* delegate,
     65     internal::ResourceMetadata* metadata,
     66     internal::FileCache* cache)
     67     : blocking_task_runner_(blocking_task_runner),
     68       delegate_(delegate),
     69       metadata_(metadata),
     70       cache_(cache),
     71       weak_ptr_factory_(this) {
     72   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
     73 }
     74 
     75 RemoveOperation::~RemoveOperation() {
     76   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
     77 }
     78 
     79 void RemoveOperation::Remove(const base::FilePath& path,
     80                              bool is_recursive,
     81                              const FileOperationCallback& callback) {
     82   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
     83   DCHECK(!callback.is_null());
     84 
     85   std::string* local_id = new std::string;
     86   base::FilePath* changed_path = new base::FilePath;
     87   ResourceEntry* entry = new ResourceEntry;
     88   base::PostTaskAndReplyWithResult(
     89       blocking_task_runner_.get(),
     90       FROM_HERE,
     91       base::Bind(&UpdateLocalState,
     92                  metadata_,
     93                  cache_,
     94                  path,
     95                  is_recursive,
     96                  local_id,
     97                  entry,
     98                  changed_path),
     99       base::Bind(&RemoveOperation::RemoveAfterUpdateLocalState,
    100                  weak_ptr_factory_.GetWeakPtr(),
    101                  callback,
    102                  base::Owned(local_id),
    103                  base::Owned(entry),
    104                  base::Owned(changed_path)));
    105 }
    106 
    107 void RemoveOperation::RemoveAfterUpdateLocalState(
    108     const FileOperationCallback& callback,
    109     const std::string* local_id,
    110     const ResourceEntry* entry,
    111     const base::FilePath* changed_path,
    112     FileError error) {
    113   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
    114   DCHECK(!callback.is_null());
    115 
    116   if (!changed_path->empty()) {
    117     FileChange changed_file;
    118     changed_file.Update(*changed_path, *entry, FileChange::DELETE);
    119     if (error == FILE_ERROR_OK) {
    120       delegate_->OnFileChangedByOperation(changed_file);
    121       delegate_->OnEntryUpdatedByOperation(*local_id);
    122     }
    123   }
    124 
    125   callback.Run(error);
    126 }
    127 
    128 }  // namespace file_system
    129 }  // namespace drive
    130