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.
5 #include "chrome/browser/chromeos/file_manager/zip_file_creator.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"
15 using content::BrowserThread
;
16 using content::UtilityProcessHost
;
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
);
27 namespace file_manager
{
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
),
36 src_relative_paths_(src_relative_paths
),
37 dest_file_(dest_file
) {
38 DCHECK(!callback_
.is_null());
41 void ZipFileCreator::Start() {
42 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
44 base::PostTaskAndReplyWithResult(
45 BrowserThread::GetBlockingPool(),
47 base::Bind(&OpenFileHandleOnBlockingThreadPool
, dest_file_
),
48 base::Bind(&ZipFileCreator::OnOpenFileHandle
, this));
51 ZipFileCreator::~ZipFileCreator() {
54 bool ZipFileCreator::OnMessageReceived(const IPC::Message
& message
) {
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)
66 void ZipFileCreator::OnProcessCrashed(int exit_code
) {
70 void ZipFileCreator::OnOpenFileHandle(base::File file
) {
71 DCHECK_CURRENTLY_ON(content::BrowserThread::UI
);
73 if (!file
.IsValid()) {
74 LOG(ERROR
) << "Failed to create dest zip file " << dest_file_
.value();
79 BrowserThread::PostTask(
83 &ZipFileCreator::StartProcessOnIOThread
, this, base::Passed(&file
)));
86 void ZipFileCreator::StartProcessOnIOThread(base::File dest_file
) {
87 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
89 base::FileDescriptor
dest_fd(dest_file
.Pass());
91 UtilityProcessHost
* host
= UtilityProcessHost::Create(
93 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI
).get());
94 host
->SetExposedDir(src_dir_
);
95 host
->Send(new ChromeUtilityMsg_CreateZipFile(src_dir_
, src_relative_paths_
,
99 void ZipFileCreator::OnCreateZipFileSucceeded() {
103 void ZipFileCreator::OnCreateZipFileFailed() {
107 void ZipFileCreator::ReportDone(bool success
) {
108 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
110 // Guard against calling observer multiple times.
111 if (!callback_
.is_null())
112 base::ResetAndReturn(&callback_
).Run(success
);
115 } // namespace file_manager