• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.
OpenFileHandleOnBlockingThreadPool(const base::FilePath & zip_path)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 
ZipFileCreator(const ResultCallback & callback,const base::FilePath & src_dir,const std::vector<base::FilePath> & src_relative_paths,const base::FilePath & dest_file)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 
Start()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 
~ZipFileCreator()51 ZipFileCreator::~ZipFileCreator() {
52 }
53 
OnMessageReceived(const IPC::Message & message)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 
OnProcessCrashed(int exit_code)66 void ZipFileCreator::OnProcessCrashed(int exit_code) {
67   ReportDone(false);
68 }
69 
OnOpenFileHandle(base::File file)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 
StartProcessOnIOThread(base::File dest_file)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 
OnCreateZipFileSucceeded()99 void ZipFileCreator::OnCreateZipFileSucceeded() {
100   ReportDone(true);
101 }
102 
OnCreateZipFileFailed()103 void ZipFileCreator::OnCreateZipFileFailed() {
104   ReportDone(false);
105 }
106 
ReportDone(bool success)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