// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "chromeos/dbus/image_burner_client.h" #include "base/bind.h" #include "base/compiler_specific.h" #include "dbus/bus.h" #include "dbus/message.h" #include "dbus/object_path.h" #include "dbus/object_proxy.h" #include "third_party/cros_system_api/dbus/service_constants.h" namespace chromeos { namespace { // The ImageBurnerClient implementation. class ImageBurnerClientImpl : public ImageBurnerClient { public: ImageBurnerClientImpl() : proxy_(NULL), weak_ptr_factory_(this) {} virtual ~ImageBurnerClientImpl() {} // ImageBurnerClient override. virtual void BurnImage(const std::string& from_path, const std::string& to_path, const ErrorCallback& error_callback) OVERRIDE { dbus::MethodCall method_call(imageburn::kImageBurnServiceInterface, imageburn::kBurnImage); dbus::MessageWriter writer(&method_call); writer.AppendString(from_path); writer.AppendString(to_path); proxy_->CallMethod(&method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, base::Bind(&ImageBurnerClientImpl::OnBurnImage, weak_ptr_factory_.GetWeakPtr(), error_callback)); } // ImageBurnerClient override. virtual void SetEventHandlers( const BurnFinishedHandler& burn_finished_handler, const BurnProgressUpdateHandler& burn_progress_update_handler) OVERRIDE { burn_finished_handler_ = burn_finished_handler; burn_progress_update_handler_ = burn_progress_update_handler; } // ImageBurnerClient override. virtual void ResetEventHandlers() OVERRIDE { burn_finished_handler_.Reset(); burn_progress_update_handler_.Reset(); } protected: virtual void Init(dbus::Bus* bus) OVERRIDE { proxy_ = bus->GetObjectProxy(imageburn::kImageBurnServiceName, dbus::ObjectPath(imageburn::kImageBurnServicePath)); proxy_->ConnectToSignal( imageburn::kImageBurnServiceInterface, imageburn::kSignalBurnFinishedName, base::Bind(&ImageBurnerClientImpl::OnBurnFinished, weak_ptr_factory_.GetWeakPtr()), base::Bind(&ImageBurnerClientImpl::OnSignalConnected, weak_ptr_factory_.GetWeakPtr())); proxy_->ConnectToSignal( imageburn::kImageBurnServiceInterface, imageburn::kSignalBurnUpdateName, base::Bind(&ImageBurnerClientImpl::OnBurnProgressUpdate, weak_ptr_factory_.GetWeakPtr()), base::Bind(&ImageBurnerClientImpl::OnSignalConnected, weak_ptr_factory_.GetWeakPtr())); } private: // Called when a response for BurnImage is received void OnBurnImage(ErrorCallback error_callback, dbus::Response* response) { if (!response) { error_callback.Run(); return; } } // Handles burn_finished signal and calls |handler|. void OnBurnFinished(dbus::Signal* signal) { dbus::MessageReader reader(signal); std::string target_path; bool success; std::string error; if (!reader.PopString(&target_path) || !reader.PopBool(&success) || !reader.PopString(&error)) { LOG(ERROR) << "Invalid signal: " << signal->ToString(); return; } if (!burn_finished_handler_.is_null()) burn_finished_handler_.Run(target_path, success, error); } // Handles burn_progress_udpate signal and calls |handler|. void OnBurnProgressUpdate(dbus::Signal* signal) { dbus::MessageReader reader(signal); std::string target_path; int64 num_bytes_burnt; int64 total_size; if (!reader.PopString(&target_path) || !reader.PopInt64(&num_bytes_burnt) || !reader.PopInt64(&total_size)) { LOG(ERROR) << "Invalid signal: " << signal->ToString(); return; } if (!burn_progress_update_handler_.is_null()) burn_progress_update_handler_.Run(target_path, num_bytes_burnt, total_size); } // Handles the result of signal connection setup. void OnSignalConnected(const std::string& interface, const std::string& signal, bool succeeded) { LOG_IF(ERROR, !succeeded) << "Connect to " << interface << " " << signal << " failed."; } dbus::ObjectProxy* proxy_; BurnFinishedHandler burn_finished_handler_; BurnProgressUpdateHandler burn_progress_update_handler_; // Note: This should remain the last member so it'll be destroyed and // invalidate its weak pointers before any other members are destroyed. base::WeakPtrFactory<ImageBurnerClientImpl> weak_ptr_factory_; DISALLOW_COPY_AND_ASSIGN(ImageBurnerClientImpl); }; } // namespace ImageBurnerClient::ImageBurnerClient() { } ImageBurnerClient::~ImageBurnerClient() { } // static ImageBurnerClient* ImageBurnerClient::Create() { return new ImageBurnerClientImpl(); } } // namespace chromeos