Home | History | Annotate | Download | only in image_writer_private
      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 
     14 ImageWriterUtilityClient::ImageWriterUtilityClient()
     15     : message_loop_proxy_(base::MessageLoopProxy::current()) {}
     16 ImageWriterUtilityClient::~ImageWriterUtilityClient() {}
     17 
     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 
     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 
     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 
     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 
     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 
    104 void ImageWriterUtilityClient::OnProcessCrashed(int exit_code) {
    105   message_loop_proxy_->PostTask(
    106       FROM_HERE, base::Bind(error_callback_, "Utility process crashed."));
    107 }
    108 
    109 void ImageWriterUtilityClient::OnProcessLaunchFailed() {
    110   message_loop_proxy_->PostTask(
    111       FROM_HERE, base::Bind(error_callback_, "Process launch failed."));
    112 }
    113 
    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 
    130 bool ImageWriterUtilityClient::Send(IPC::Message* msg) {
    131   return utility_process_host_ && utility_process_host_->Send(msg);
    132 }
    133 
    134 void ImageWriterUtilityClient::OnWriteImageSucceeded() {
    135   if (!success_callback_.is_null()) {
    136     message_loop_proxy_->PostTask(FROM_HERE, success_callback_);
    137   }
    138 }
    139 
    140 void ImageWriterUtilityClient::OnWriteImageCancelled() {
    141   if (!cancel_callback_.is_null()) {
    142     message_loop_proxy_->PostTask(FROM_HERE, cancel_callback_);
    143   }
    144 }
    145 
    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 
    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