Home | History | Annotate | Download | only in file_manager
      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/file_manager/zip_file_creator.h"
      6 
      7 #include "base/bind.h"
      8 #include "base/callback_helpers.h"
      9 #include "base/message_loop/message_loop.h"
     10 #include "base/threading/sequenced_worker_pool.h"
     11 #include "chrome/common/chrome_utility_messages.h"
     12 #include "content/public/browser/browser_thread.h"
     13 #include "content/public/browser/utility_process_host.h"
     14 
     15 using content::BrowserThread;
     16 using content::UtilityProcessHost;
     17 
     18 namespace {
     19 
     20 // Creates the destination zip file only if it does not already exist.
     21 base::File OpenFileHandleOnBlockingThreadPool(const base::FilePath& zip_path) {
     22   return base::File(zip_path, base::File::FLAG_CREATE | base::File::FLAG_WRITE);
     23 }
     24 
     25 }  // namespace
     26 
     27 namespace file_manager {
     28 
     29 ZipFileCreator::ZipFileCreator(
     30     const ResultCallback& callback,
     31     const base::FilePath& src_dir,
     32     const std::vector<base::FilePath>& src_relative_paths,
     33     const base::FilePath& dest_file)
     34     : callback_(callback),
     35       src_dir_(src_dir),
     36       src_relative_paths_(src_relative_paths),
     37       dest_file_(dest_file) {
     38   DCHECK(!callback_.is_null());
     39 }
     40 
     41 void ZipFileCreator::Start() {
     42   DCHECK_CURRENTLY_ON(BrowserThread::UI);
     43 
     44   base::PostTaskAndReplyWithResult(
     45       BrowserThread::GetBlockingPool(),
     46       FROM_HERE,
     47       base::Bind(&OpenFileHandleOnBlockingThreadPool, dest_file_),
     48       base::Bind(&ZipFileCreator::OnOpenFileHandle, this));
     49 }
     50 
     51 ZipFileCreator::~ZipFileCreator() {
     52 }
     53 
     54 bool ZipFileCreator::OnMessageReceived(const IPC::Message& message) {
     55   bool handled = true;
     56   IPC_BEGIN_MESSAGE_MAP(ZipFileCreator, message)
     57     IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_CreateZipFile_Succeeded,
     58                         OnCreateZipFileSucceeded)
     59     IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_CreateZipFile_Failed,
     60                         OnCreateZipFileFailed)
     61     IPC_MESSAGE_UNHANDLED(handled = false)
     62   IPC_END_MESSAGE_MAP()
     63   return handled;
     64 }
     65 
     66 void ZipFileCreator::OnProcessCrashed(int exit_code) {
     67   ReportDone(false);
     68 }
     69 
     70 void ZipFileCreator::OnOpenFileHandle(base::File file) {
     71   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
     72 
     73   if (!file.IsValid()) {
     74     LOG(ERROR) << "Failed to create dest zip file " << dest_file_.value();
     75     ReportDone(false);
     76     return;
     77   }
     78 
     79   BrowserThread::PostTask(
     80       BrowserThread::IO,
     81       FROM_HERE,
     82       base::Bind(
     83           &ZipFileCreator::StartProcessOnIOThread, this, base::Passed(&file)));
     84 }
     85 
     86 void ZipFileCreator::StartProcessOnIOThread(base::File dest_file) {
     87   DCHECK_CURRENTLY_ON(BrowserThread::IO);
     88 
     89   base::FileDescriptor dest_fd(dest_file.Pass());
     90 
     91   UtilityProcessHost* host = UtilityProcessHost::Create(
     92       this,
     93       BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI).get());
     94   host->SetExposedDir(src_dir_);
     95   host->Send(new ChromeUtilityMsg_CreateZipFile(src_dir_, src_relative_paths_,
     96                                                 dest_fd));
     97 }
     98 
     99 void ZipFileCreator::OnCreateZipFileSucceeded() {
    100   ReportDone(true);
    101 }
    102 
    103 void ZipFileCreator::OnCreateZipFileFailed() {
    104   ReportDone(false);
    105 }
    106 
    107 void ZipFileCreator::ReportDone(bool success) {
    108   DCHECK_CURRENTLY_ON(BrowserThread::UI);
    109 
    110   // Guard against calling observer multiple times.
    111   if (!callback_.is_null())
    112     base::ResetAndReturn(&callback_).Run(success);
    113 }
    114 
    115 }  // namespace file_manager
    116