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/extensions/chrome_utility_extensions_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   }
    101 }
    102 
    103 void ImageWriterUtilityClient::OnProcessCrashed(int exit_code) {
    104   message_loop_proxy_->PostTask(
    105       FROM_HERE, base::Bind(error_callback_, "Utility process crashed."));
    106 }
    107 
    108 void ImageWriterUtilityClient::OnProcessLaunchFailed() {
    109   message_loop_proxy_->PostTask(
    110       FROM_HERE, base::Bind(error_callback_, "Process launch failed."));
    111 }
    112 
    113 bool ImageWriterUtilityClient::OnMessageReceived(const IPC::Message& message) {
    114   bool handled = true;
    115   IPC_BEGIN_MESSAGE_MAP(ImageWriterUtilityClient, message)
    116   IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_ImageWriter_Succeeded,
    117                       OnWriteImageSucceeded)
    118   IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_ImageWriter_Cancelled,
    119                       OnWriteImageCancelled)
    120   IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_ImageWriter_Failed,
    121                       OnWriteImageFailed)
    122   IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_ImageWriter_Progress,
    123                       OnWriteImageProgress)
    124   IPC_MESSAGE_UNHANDLED(handled = false)
    125   IPC_END_MESSAGE_MAP()
    126   return handled;
    127 }
    128 
    129 bool ImageWriterUtilityClient::Send(IPC::Message* msg) {
    130   return utility_process_host_ && utility_process_host_->Send(msg);
    131 }
    132 
    133 void ImageWriterUtilityClient::OnWriteImageSucceeded() {
    134   if (!success_callback_.is_null()) {
    135     message_loop_proxy_->PostTask(FROM_HERE, success_callback_);
    136   }
    137 }
    138 
    139 void ImageWriterUtilityClient::OnWriteImageCancelled() {
    140   if (!cancel_callback_.is_null()) {
    141     message_loop_proxy_->PostTask(FROM_HERE, cancel_callback_);
    142   }
    143 }
    144 
    145 void ImageWriterUtilityClient::OnWriteImageFailed(const std::string& message) {
    146   if (!error_callback_.is_null()) {
    147     message_loop_proxy_->PostTask(FROM_HERE,
    148                                   base::Bind(error_callback_, message));
    149   }
    150 }
    151 
    152 void ImageWriterUtilityClient::OnWriteImageProgress(int64 progress) {
    153   if (!progress_callback_.is_null()) {
    154     message_loop_proxy_->PostTask(FROM_HERE,
    155                                   base::Bind(progress_callback_, progress));
    156   }
    157 }
    158