zip_file_creator.cc revision a02191e04bc25c4935f804f2c080ae28663d096d
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/command_line.h" 9#include "base/files/file_util_proxy.h" 10#include "base/memory/scoped_handle.h" 11#include "base/message_loop/message_loop.h" 12#include "base/path_service.h" 13#include "base/threading/sequenced_worker_pool.h" 14#include "chrome/common/chrome_paths.h" 15#include "chrome/common/chrome_switches.h" 16#include "chrome/common/chrome_utility_messages.h" 17#include "content/public/browser/browser_thread.h" 18#include "content/public/browser/utility_process_host.h" 19#include "grit/generated_resources.h" 20 21using content::BrowserThread; 22using content::UtilityProcessHost; 23 24namespace file_manager { 25 26ZipFileCreator::ZipFileCreator( 27 Observer* observer, 28 const base::FilePath& src_dir, 29 const std::vector<base::FilePath>& src_relative_paths, 30 const base::FilePath& dest_file) 31 : thread_identifier_(BrowserThread::ID_COUNT), 32 observer_(observer), 33 src_dir_(src_dir), 34 src_relative_paths_(src_relative_paths), 35 dest_file_(dest_file), 36 got_response_(false) { 37} 38 39void ZipFileCreator::Start() { 40 CHECK(BrowserThread::GetCurrentThreadIdentifier(&thread_identifier_)); 41 BrowserThread::GetBlockingPool()->PostTask( 42 FROM_HERE, 43 base::Bind(&ZipFileCreator::OpenFileHandleOnBlockingThreadPool, this)); 44} 45 46ZipFileCreator::~ZipFileCreator() { 47} 48 49bool ZipFileCreator::OnMessageReceived(const IPC::Message& message) { 50 bool handled = true; 51 IPC_BEGIN_MESSAGE_MAP(ZipFileCreator, message) 52 IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_CreateZipFile_Succeeded, 53 OnCreateZipFileSucceeded) 54 IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_CreateZipFile_Failed, 55 OnCreateZipFileFailed) 56 IPC_MESSAGE_UNHANDLED(handled = false) 57 IPC_END_MESSAGE_MAP() 58 return handled; 59} 60 61void ZipFileCreator::OnProcessCrashed(int exit_code) { 62 // Don't report crashes if they happen after we got a response. 63 if (got_response_) 64 return; 65 66 // Utility process crashed while trying to create the zip file. 67 ReportDone(false); 68} 69 70void ZipFileCreator::OpenFileHandleOnBlockingThreadPool() { 71 // Create the destination zip file only if it does not already exist. 72 base::File dest_file(dest_file_, 73 base::File::FLAG_CREATE | base::File::FLAG_WRITE); 74 75 if (!dest_file.IsValid()) { 76 LOG(ERROR) << "Failed to create dest zip file " << dest_file_.value(); 77 78 BrowserThread::GetMessageLoopProxyForThread(thread_identifier_)->PostTask( 79 FROM_HERE, 80 base::Bind(&ZipFileCreator::ReportDone, this, false)); 81 return; 82 } 83 84 BrowserThread::PostTask( 85 BrowserThread::IO, FROM_HERE, 86 base::Bind(&ZipFileCreator::StartProcessOnIOThread, this, 87 Passed(&dest_file))); 88} 89 90void ZipFileCreator::StartProcessOnIOThread(base::File dest_file) { 91 base::FileDescriptor dest_fd(dest_file.Pass()); 92 93 UtilityProcessHost* host = UtilityProcessHost::Create( 94 this, 95 BrowserThread::GetMessageLoopProxyForThread(thread_identifier_).get()); 96 host->SetExposedDir(src_dir_); 97 host->Send(new ChromeUtilityMsg_CreateZipFile(src_dir_, src_relative_paths_, 98 dest_fd)); 99} 100 101void ZipFileCreator::OnCreateZipFileSucceeded() { 102 ReportDone(true); 103} 104 105void ZipFileCreator::OnCreateZipFileFailed() { 106 ReportDone(false); 107} 108 109void ZipFileCreator::ReportDone(bool success) { 110 // Skip check for unittests. 111 if (thread_identifier_ != BrowserThread::ID_COUNT) 112 DCHECK(BrowserThread::CurrentlyOn(thread_identifier_)); 113 114 // Guard against calling observer multiple times. 115 if (got_response_) 116 return; 117 118 got_response_ = true; 119 observer_->OnZipDone(success); 120} 121 122} // namespace file_manager 123