• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2014 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 "base/bind.h"
6 #include "base/message_loop/message_loop.h"
7 #include "chrome/browser/browser_process.h"
8 #include "chrome/browser/extensions/api/image_writer_private/image_writer_utility_client.h"
9 #include "chrome/common/chrome_utility_messages.h"
10 #include "content/public/browser/browser_thread.h"
11 
12 using content::BrowserThread;
13 
ImageWriterUtilityClient()14 ImageWriterUtilityClient::ImageWriterUtilityClient()
15     : message_loop_proxy_(base::MessageLoopProxy::current()) {}
~ImageWriterUtilityClient()16 ImageWriterUtilityClient::~ImageWriterUtilityClient() {}
17 
Write(const ProgressCallback & progress_callback,const SuccessCallback & success_callback,const ErrorCallback & error_callback,const base::FilePath & source,const base::FilePath & target)18 void ImageWriterUtilityClient::Write(const ProgressCallback& progress_callback,
19                                      const SuccessCallback& success_callback,
20                                      const ErrorCallback& error_callback,
21                                      const base::FilePath& source,
22                                      const base::FilePath& target) {
23   DCHECK_CURRENTLY_ON(BrowserThread::IO);
24 
25   StartHost();
26 
27   progress_callback_ = progress_callback;
28   success_callback_ = success_callback;
29   error_callback_ = error_callback;
30 
31   if (!Send(new ChromeUtilityMsg_ImageWriter_Write(source, target))) {
32     DLOG(ERROR) << "Unable to send Write message to Utility Process.";
33     message_loop_proxy_->PostTask(
34         FROM_HERE, base::Bind(error_callback_, "IPC communication failed"));
35   }
36 }
37 
Verify(const ProgressCallback & progress_callback,const SuccessCallback & success_callback,const ErrorCallback & error_callback,const base::FilePath & source,const base::FilePath & target)38 void ImageWriterUtilityClient::Verify(const ProgressCallback& progress_callback,
39                                       const SuccessCallback& success_callback,
40                                       const ErrorCallback& error_callback,
41                                       const base::FilePath& source,
42                                       const base::FilePath& target) {
43   DCHECK_CURRENTLY_ON(BrowserThread::IO);
44 
45   StartHost();
46 
47   progress_callback_ = progress_callback;
48   success_callback_ = success_callback;
49   error_callback_ = error_callback;
50 
51   if (!Send(new ChromeUtilityMsg_ImageWriter_Verify(source, target))) {
52     DLOG(ERROR) << "Unable to send Verify message to Utility Process.";
53     message_loop_proxy_->PostTask(
54         FROM_HERE, base::Bind(error_callback_, "IPC communication failed"));
55   }
56 }
57 
Cancel(const CancelCallback & cancel_callback)58 void ImageWriterUtilityClient::Cancel(const CancelCallback& cancel_callback) {
59   DCHECK_CURRENTLY_ON(BrowserThread::IO);
60 
61   if (!utility_process_host_) {
62     // If we haven't connected, there is nothing to cancel.
63     message_loop_proxy_->PostTask(FROM_HERE, cancel_callback);
64     return;
65   }
66 
67   cancel_callback_ = cancel_callback;
68 
69   if (!Send(new ChromeUtilityMsg_ImageWriter_Cancel())) {
70     DLOG(ERROR) << "Unable to send Cancel message to Utility Process.";
71   }
72 }
73 
Shutdown()74 void ImageWriterUtilityClient::Shutdown() {
75   if (utility_process_host_ &&
76       Send(new ChromeUtilityMsg_ImageWriter_Cancel())) {
77     utility_process_host_->EndBatchMode();
78   }
79 
80   // Clear handlers to not hold any reference to the caller.
81   success_callback_ = base::Closure();
82   progress_callback_ = base::Callback<void(int64)>();
83   error_callback_ = base::Callback<void(const std::string&)>();
84   cancel_callback_ = base::Closure();
85 }
86 
StartHost()87 void ImageWriterUtilityClient::StartHost() {
88   if (!utility_process_host_) {
89     scoped_refptr<base::SequencedTaskRunner> task_runner =
90         base::MessageLoop::current()->message_loop_proxy();
91     utility_process_host_ = content::UtilityProcessHost::Create(
92                                 this, task_runner.get())->AsWeakPtr();
93 
94 #if defined(OS_WIN)
95     utility_process_host_->ElevatePrivileges();
96 #else
97     utility_process_host_->DisableSandbox();
98 #endif
99     utility_process_host_->StartBatchMode();
100     utility_process_host_->DisableSandbox();
101   }
102 }
103 
OnProcessCrashed(int exit_code)104 void ImageWriterUtilityClient::OnProcessCrashed(int exit_code) {
105   message_loop_proxy_->PostTask(
106       FROM_HERE, base::Bind(error_callback_, "Utility process crashed."));
107 }
108 
OnProcessLaunchFailed()109 void ImageWriterUtilityClient::OnProcessLaunchFailed() {
110   message_loop_proxy_->PostTask(
111       FROM_HERE, base::Bind(error_callback_, "Process launch failed."));
112 }
113 
OnMessageReceived(const IPC::Message & message)114 bool ImageWriterUtilityClient::OnMessageReceived(const IPC::Message& message) {
115   bool handled = true;
116   IPC_BEGIN_MESSAGE_MAP(ImageWriterUtilityClient, message)
117   IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_ImageWriter_Succeeded,
118                       OnWriteImageSucceeded)
119   IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_ImageWriter_Cancelled,
120                       OnWriteImageCancelled)
121   IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_ImageWriter_Failed,
122                       OnWriteImageFailed)
123   IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_ImageWriter_Progress,
124                       OnWriteImageProgress)
125   IPC_MESSAGE_UNHANDLED(handled = false)
126   IPC_END_MESSAGE_MAP()
127   return handled;
128 }
129 
Send(IPC::Message * msg)130 bool ImageWriterUtilityClient::Send(IPC::Message* msg) {
131   return utility_process_host_ && utility_process_host_->Send(msg);
132 }
133 
OnWriteImageSucceeded()134 void ImageWriterUtilityClient::OnWriteImageSucceeded() {
135   if (!success_callback_.is_null()) {
136     message_loop_proxy_->PostTask(FROM_HERE, success_callback_);
137   }
138 }
139 
OnWriteImageCancelled()140 void ImageWriterUtilityClient::OnWriteImageCancelled() {
141   if (!cancel_callback_.is_null()) {
142     message_loop_proxy_->PostTask(FROM_HERE, cancel_callback_);
143   }
144 }
145 
OnWriteImageFailed(const std::string & message)146 void ImageWriterUtilityClient::OnWriteImageFailed(const std::string& message) {
147   if (!error_callback_.is_null()) {
148     message_loop_proxy_->PostTask(FROM_HERE,
149                                   base::Bind(error_callback_, message));
150   }
151 }
152 
OnWriteImageProgress(int64 progress)153 void ImageWriterUtilityClient::OnWriteImageProgress(int64 progress) {
154   if (!progress_callback_.is_null()) {
155     message_loop_proxy_->PostTask(FROM_HERE,
156                                   base::Bind(progress_callback_, progress));
157   }
158 }
159