Home | History | Annotate | Download | only in dbus
      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 "chromeos/dbus/image_burner_client.h"
      6 
      7 #include "base/bind.h"
      8 #include "base/compiler_specific.h"
      9 #include "chromeos/dbus/fake_image_burner_client.h"
     10 #include "dbus/bus.h"
     11 #include "dbus/message.h"
     12 #include "dbus/object_path.h"
     13 #include "dbus/object_proxy.h"
     14 #include "third_party/cros_system_api/dbus/service_constants.h"
     15 
     16 namespace chromeos {
     17 
     18 namespace {
     19 
     20 // The ImageBurnerClient implementation.
     21 class ImageBurnerClientImpl : public ImageBurnerClient {
     22  public:
     23   explicit ImageBurnerClientImpl(dbus::Bus* bus)
     24       : proxy_(NULL),
     25         weak_ptr_factory_(this) {
     26     proxy_ = bus->GetObjectProxy(
     27         imageburn::kImageBurnServiceName,
     28         dbus::ObjectPath(imageburn::kImageBurnServicePath));
     29     proxy_->ConnectToSignal(
     30         imageburn::kImageBurnServiceInterface,
     31         imageburn::kSignalBurnFinishedName,
     32         base::Bind(&ImageBurnerClientImpl::OnBurnFinished,
     33                    weak_ptr_factory_.GetWeakPtr()),
     34         base::Bind(&ImageBurnerClientImpl::OnSignalConnected,
     35                    weak_ptr_factory_.GetWeakPtr()));
     36     proxy_->ConnectToSignal(
     37         imageburn::kImageBurnServiceInterface,
     38         imageburn::kSignalBurnUpdateName,
     39         base::Bind(&ImageBurnerClientImpl::OnBurnProgressUpdate,
     40                    weak_ptr_factory_.GetWeakPtr()),
     41         base::Bind(&ImageBurnerClientImpl::OnSignalConnected,
     42                    weak_ptr_factory_.GetWeakPtr()));
     43   }
     44   virtual ~ImageBurnerClientImpl() {}
     45 
     46   // ImageBurnerClient override.
     47   virtual void BurnImage(const std::string& from_path,
     48                          const std::string& to_path,
     49                          const ErrorCallback& error_callback) OVERRIDE {
     50     dbus::MethodCall method_call(imageburn::kImageBurnServiceInterface,
     51                                  imageburn::kBurnImage);
     52     dbus::MessageWriter writer(&method_call);
     53     writer.AppendString(from_path);
     54     writer.AppendString(to_path);
     55     proxy_->CallMethod(&method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
     56                        base::Bind(&ImageBurnerClientImpl::OnBurnImage,
     57                                   weak_ptr_factory_.GetWeakPtr(),
     58                                   error_callback));
     59   }
     60 
     61   // ImageBurnerClient override.
     62   virtual void SetEventHandlers(
     63       const BurnFinishedHandler& burn_finished_handler,
     64       const BurnProgressUpdateHandler& burn_progress_update_handler) OVERRIDE {
     65     burn_finished_handler_ = burn_finished_handler;
     66     burn_progress_update_handler_ = burn_progress_update_handler;
     67   }
     68 
     69   // ImageBurnerClient override.
     70   virtual void ResetEventHandlers() OVERRIDE {
     71     burn_finished_handler_.Reset();
     72     burn_progress_update_handler_.Reset();
     73   }
     74 
     75  private:
     76   // Called when a response for BurnImage is received
     77   void OnBurnImage(ErrorCallback error_callback, dbus::Response* response) {
     78     if (!response) {
     79       error_callback.Run();
     80       return;
     81     }
     82   }
     83 
     84   // Handles burn_finished signal and calls |handler|.
     85   void OnBurnFinished(dbus::Signal* signal) {
     86     dbus::MessageReader reader(signal);
     87     std::string target_path;
     88     bool success;
     89     std::string error;
     90     if (!reader.PopString(&target_path) ||
     91         !reader.PopBool(&success) ||
     92         !reader.PopString(&error)) {
     93       LOG(ERROR) << "Invalid signal: " << signal->ToString();
     94       return;
     95     }
     96     if (!burn_finished_handler_.is_null())
     97       burn_finished_handler_.Run(target_path, success, error);
     98   }
     99 
    100   // Handles burn_progress_udpate signal and calls |handler|.
    101   void OnBurnProgressUpdate(dbus::Signal* signal) {
    102     dbus::MessageReader reader(signal);
    103     std::string target_path;
    104     int64 num_bytes_burnt;
    105     int64 total_size;
    106     if (!reader.PopString(&target_path) ||
    107         !reader.PopInt64(&num_bytes_burnt) ||
    108         !reader.PopInt64(&total_size)) {
    109       LOG(ERROR) << "Invalid signal: " << signal->ToString();
    110       return;
    111     }
    112     if (!burn_progress_update_handler_.is_null())
    113       burn_progress_update_handler_.Run(target_path, num_bytes_burnt,
    114                                         total_size);
    115   }
    116 
    117   // Handles the result of signal connection setup.
    118   void OnSignalConnected(const std::string& interface,
    119                          const std::string& signal,
    120                          bool succeeded) {
    121     LOG_IF(ERROR, !succeeded) << "Connect to " << interface << " " <<
    122         signal << " failed.";
    123   }
    124 
    125   dbus::ObjectProxy* proxy_;
    126   BurnFinishedHandler burn_finished_handler_;
    127   BurnProgressUpdateHandler burn_progress_update_handler_;
    128 
    129   // Note: This should remain the last member so it'll be destroyed and
    130   // invalidate its weak pointers before any other members are destroyed.
    131   base::WeakPtrFactory<ImageBurnerClientImpl> weak_ptr_factory_;
    132 
    133   DISALLOW_COPY_AND_ASSIGN(ImageBurnerClientImpl);
    134 };
    135 
    136 }  // namespace
    137 
    138 ImageBurnerClient::ImageBurnerClient() {
    139 }
    140 
    141 ImageBurnerClient::~ImageBurnerClient() {
    142 }
    143 
    144 // static
    145 ImageBurnerClient* ImageBurnerClient::Create(DBusClientImplementationType type,
    146                                              dbus::Bus* bus) {
    147   if (type == REAL_DBUS_CLIENT_IMPLEMENTATION)
    148     return new ImageBurnerClientImpl(bus);
    149   DCHECK_EQ(STUB_DBUS_CLIENT_IMPLEMENTATION, type);
    150   return new FakeImageBurnerClient();
    151 }
    152 
    153 }  // namespace chromeos
    154