cros_disks_client.cc revision d0247b1b59f9c528cb6df88b4f2b9afaf80d181e
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chromeos/dbus/cros_disks_client.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <map>
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h"
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/chromeos/chromeos_version.h"
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/file_util.h"
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/files/file_path.h"
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/location.h"
14868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/message_loop/message_loop_proxy.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/stl_util.h"
16868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/stringprintf.h"
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/task_runner_util.h"
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/threading/worker_pool.h"
197dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "base/values.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "dbus/bus.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "dbus/message.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "dbus/object_path.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "dbus/object_proxy.h"
247dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "dbus/values_util.h"
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "third_party/cros_system_api/dbus/service_constants.h"
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace chromeos {
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char* kDefaultMountOptions[] = {
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "rw",
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "nodev",
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "noexec",
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "nosuid",
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char* kDefaultUnmountOptions[] = {
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "force",
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kLazyUnmountOption[] = "lazy";
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kMountLabelOption[] = "mountlabel";
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Checks if retrieved media type is in boundaries of DeviceMediaType.
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool IsValidMediaType(uint32 type) {
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return type < static_cast<uint32>(cros_disks::DEVICE_MEDIA_NUM_VALUES);
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Translates enum used in cros-disks to enum used in Chrome.
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Note that we could just do static_cast, but this is less sensitive to
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// changes in cros-disks.
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DeviceType DeviceMediaTypeToDeviceType(uint32 media_type_uint32) {
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!IsValidMediaType(media_type_uint32))
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return DEVICE_TYPE_UNKNOWN;
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  cros_disks::DeviceMediaType media_type =
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      cros_disks::DeviceMediaType(media_type_uint32);
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (media_type) {
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case(cros_disks::DEVICE_MEDIA_UNKNOWN):
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return DEVICE_TYPE_UNKNOWN;
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case(cros_disks::DEVICE_MEDIA_USB):
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return DEVICE_TYPE_USB;
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case(cros_disks::DEVICE_MEDIA_SD):
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return DEVICE_TYPE_SD;
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case(cros_disks::DEVICE_MEDIA_OPTICAL_DISC):
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return DEVICE_TYPE_OPTICAL_DISC;
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case(cros_disks::DEVICE_MEDIA_MOBILE):
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return DEVICE_TYPE_MOBILE;
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case(cros_disks::DEVICE_MEDIA_DVD):
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return DEVICE_TYPE_DVD;
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    default:
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return DEVICE_TYPE_UNKNOWN;
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The CrosDisksClient implementation.
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class CrosDisksClientImpl : public CrosDisksClient {
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
82424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  CrosDisksClientImpl() : proxy_(NULL), weak_ptr_factory_(this) {}
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // CrosDisksClient override.
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void Mount(const std::string& source_path,
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     const std::string& source_format,
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     const std::string& mount_label,
887dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                     const base::Closure& callback,
897dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                     const base::Closure& error_callback) OVERRIDE {
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    dbus::MethodCall method_call(cros_disks::kCrosDisksInterface,
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 cros_disks::kMount);
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    dbus::MessageWriter writer(&method_call);
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    writer.AppendString(source_path);
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    writer.AppendString(source_format);
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::vector<std::string> mount_options(kDefaultMountOptions,
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                           kDefaultMountOptions +
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                           arraysize(kDefaultMountOptions));
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!mount_label.empty()) {
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      std::string mount_label_option = base::StringPrintf("%s=%s",
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                          kMountLabelOption,
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                          mount_label.c_str());
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      mount_options.push_back(mount_label_option);
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    writer.AppendArrayOfStrings(mount_options);
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    proxy_->CallMethod(&method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       base::Bind(&CrosDisksClientImpl::OnMount,
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  weak_ptr_factory_.GetWeakPtr(),
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  callback,
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  error_callback));
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // CrosDisksClient override.
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void Unmount(const std::string& device_path,
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       UnmountOptions options,
115eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                       const base::Closure& callback,
116eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                       const base::Closure& error_callback) OVERRIDE {
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    dbus::MethodCall method_call(cros_disks::kCrosDisksInterface,
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 cros_disks::kUnmount);
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    dbus::MessageWriter writer(&method_call);
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    writer.AppendString(device_path);
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::vector<std::string> unmount_options(
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        kDefaultUnmountOptions,
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        kDefaultUnmountOptions + arraysize(kDefaultUnmountOptions));
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (options == UNMOUNT_OPTIONS_LAZY)
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      unmount_options.push_back(kLazyUnmountOption);
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    writer.AppendArrayOfStrings(unmount_options);
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    proxy_->CallMethod(&method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       base::Bind(&CrosDisksClientImpl::OnUnmount,
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  weak_ptr_factory_.GetWeakPtr(),
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  callback,
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  error_callback));
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // CrosDisksClient override.
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void EnumerateAutoMountableDevices(
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const EnumerateAutoMountableDevicesCallback& callback,
1397dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      const base::Closure& error_callback) OVERRIDE {
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    dbus::MethodCall method_call(cros_disks::kCrosDisksInterface,
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 cros_disks::kEnumerateAutoMountableDevices);
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    proxy_->CallMethod(
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&CrosDisksClientImpl::OnEnumerateAutoMountableDevices,
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   weak_ptr_factory_.GetWeakPtr(),
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   callback,
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   error_callback));
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // CrosDisksClient override.
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void FormatDevice(const std::string& device_path,
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            const std::string& filesystem,
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            const FormatDeviceCallback& callback,
1547dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                            const base::Closure& error_callback) OVERRIDE {
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    dbus::MethodCall method_call(cros_disks::kCrosDisksInterface,
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 cros_disks::kFormatDevice);
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    dbus::MessageWriter writer(&method_call);
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    writer.AppendString(device_path);
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    writer.AppendString(filesystem);
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    proxy_->CallMethod(&method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       base::Bind(&CrosDisksClientImpl::OnFormatDevice,
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  weak_ptr_factory_.GetWeakPtr(),
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  callback,
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  error_callback));
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // CrosDisksClient override.
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void GetDeviceProperties(
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const std::string& device_path,
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const GetDevicePropertiesCallback& callback,
1717dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      const base::Closure& error_callback) OVERRIDE {
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    dbus::MethodCall method_call(cros_disks::kCrosDisksInterface,
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 cros_disks::kGetDeviceProperties);
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    dbus::MessageWriter writer(&method_call);
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    writer.AppendString(device_path);
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    proxy_->CallMethod(&method_call,
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       base::Bind(&CrosDisksClientImpl::OnGetDeviceProperties,
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  weak_ptr_factory_.GetWeakPtr(),
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  device_path,
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  callback,
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  error_callback));
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // CrosDisksClient override.
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void SetUpConnections(
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const MountEventHandler& mount_event_handler,
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const MountCompletedHandler& mount_completed_handler) OVERRIDE {
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    static const SignalEventTuple kSignalEventTuples[] = {
1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      { cros_disks::kDeviceAdded, CROS_DISKS_DEVICE_ADDED },
1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      { cros_disks::kDeviceScanned, CROS_DISKS_DEVICE_SCANNED },
1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      { cros_disks::kDeviceRemoved, CROS_DISKS_DEVICE_REMOVED },
1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      { cros_disks::kDiskAdded, CROS_DISKS_DISK_ADDED },
1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      { cros_disks::kDiskChanged, CROS_DISKS_DISK_CHANGED },
1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      { cros_disks::kDiskRemoved, CROS_DISKS_DISK_REMOVED },
1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      { cros_disks::kFormattingFinished, CROS_DISKS_FORMATTING_FINISHED },
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const size_t kNumSignalEventTuples = arraysize(kSignalEventTuples);
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (size_t i = 0; i < kNumSignalEventTuples; ++i) {
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      proxy_->ConnectToSignal(
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          cros_disks::kCrosDisksInterface,
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          kSignalEventTuples[i].signal_name,
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          base::Bind(&CrosDisksClientImpl::OnMountEvent,
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     weak_ptr_factory_.GetWeakPtr(),
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     kSignalEventTuples[i].event_type,
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     mount_event_handler),
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          base::Bind(&CrosDisksClientImpl::OnSignalConnected,
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     weak_ptr_factory_.GetWeakPtr()));
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    proxy_->ConnectToSignal(
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        cros_disks::kCrosDisksInterface,
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        cros_disks::kMountCompleted,
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&CrosDisksClientImpl::OnMountCompleted,
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   weak_ptr_factory_.GetWeakPtr(),
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   mount_completed_handler),
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&CrosDisksClientImpl::OnSignalConnected,
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   weak_ptr_factory_.GetWeakPtr()));
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
221424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) protected:
222424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  virtual void Init(dbus::Bus* bus) OVERRIDE {
223424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    proxy_ = bus->GetObjectProxy(
224424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)        cros_disks::kCrosDisksServiceName,
225424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)        dbus::ObjectPath(cros_disks::kCrosDisksServicePath));
226424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  }
227424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // A struct to contain a pair of signal name and mount event type.
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Used by SetUpConnections.
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  struct SignalEventTuple {
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char *signal_name;
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MountEventType event_type;
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Handles the result of Mount and calls |callback| or |error_callback|.
2377dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  void OnMount(const base::Closure& callback,
2387dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch               const base::Closure& error_callback,
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               dbus::Response* response) {
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!response) {
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      error_callback.Run();
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return;
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    callback.Run();
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Handles the result of Unount and calls |callback| or |error_callback|.
248eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  void OnUnmount(const base::Closure& callback,
249eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                 const base::Closure& error_callback,
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 dbus::Response* response) {
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!response) {
252eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      error_callback.Run();
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return;
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
255d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
256d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    // Temporarly allow Unmount method to report failure both by setting dbus
257d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    // error (in which case response is not set) and by returning mount error
258d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    // different from MOUNT_ERROR_NONE. This is done so we can change Unmount
259d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    // method to return mount error (http://crbug.com/288974) without breaking
260d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    // Chrome.
261d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    // TODO(tbarzic): When Unmount implementation is changed on cros disks side,
262d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    // make this fail if reader is not able to read the error code value from
263d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    // the response.
264d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    dbus::MessageReader reader(response);
265d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    unsigned int error_code;
266d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    if (reader.PopUint32(&error_code) &&
267d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        static_cast<MountError>(error_code) != MOUNT_ERROR_NONE) {
268d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      error_callback.Run();
269d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      return;
270d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    }
271d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
272eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    callback.Run();
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Handles the result of EnumerateAutoMountableDevices and calls |callback| or
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // |error_callback|.
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void OnEnumerateAutoMountableDevices(
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const EnumerateAutoMountableDevicesCallback& callback,
2797dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      const base::Closure& error_callback,
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      dbus::Response* response) {
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!response) {
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      error_callback.Run();
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return;
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    dbus::MessageReader reader(response);
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::vector<std::string> device_paths;
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!reader.PopArrayOfStrings(&device_paths)) {
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      LOG(ERROR) << "Invalid response: " << response->ToString();
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      error_callback.Run();
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return;
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    callback.Run(device_paths);
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Handles the result of FormatDevice and calls |callback| or
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // |error_callback|.
297eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  void OnFormatDevice(const FormatDeviceCallback& callback,
2987dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                      const base::Closure& error_callback,
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      dbus::Response* response) {
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!response) {
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      error_callback.Run();
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return;
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    dbus::MessageReader reader(response);
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool success = false;
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!reader.PopBool(&success)) {
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      LOG(ERROR) << "Invalid response: " << response->ToString();
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      error_callback.Run();
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return;
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
311eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    callback.Run(success);
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Handles the result of GetDeviceProperties and calls |callback| or
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // |error_callback|.
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void OnGetDeviceProperties(const std::string& device_path,
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             const GetDevicePropertiesCallback& callback,
3187dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                             const base::Closure& error_callback,
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             dbus::Response* response) {
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!response) {
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      error_callback.Run();
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return;
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DiskInfo disk(device_path, response);
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    callback.Run(disk);
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Handles mount event signals and calls |handler|.
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void OnMountEvent(MountEventType event_type,
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    MountEventHandler handler,
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    dbus::Signal* signal) {
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    dbus::MessageReader reader(signal);
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string device;
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!reader.PopString(&device)) {
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      LOG(ERROR) << "Invalid signal: " << signal->ToString();
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return;
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    handler.Run(event_type, device);
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Handles MountCompleted signal and calls |handler|.
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void OnMountCompleted(MountCompletedHandler handler, dbus::Signal* signal) {
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    dbus::MessageReader reader(signal);
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unsigned int error_code = 0;
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string source_path;
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unsigned int mount_type = 0;
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string mount_path;
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!reader.PopUint32(&error_code) ||
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        !reader.PopString(&source_path) ||
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        !reader.PopUint32(&mount_type) ||
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        !reader.PopString(&mount_path)) {
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      LOG(ERROR) << "Invalid signal: " << signal->ToString();
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return;
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    handler.Run(static_cast<MountError>(error_code), source_path,
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                static_cast<MountType>(mount_type), mount_path);
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Handles the result of signal connection setup.
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void OnSignalConnected(const std::string& interface,
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         const std::string& signal,
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         bool succeeded) {
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LOG_IF(ERROR, !succeeded) << "Connect to " << interface << " " <<
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        signal << " failed.";
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  dbus::ObjectProxy* proxy_;
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Note: This should remain the last member so it'll be destroyed and
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // invalidate its weak pointers before any other members are destroyed.
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::WeakPtrFactory<CrosDisksClientImpl> weak_ptr_factory_;
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(CrosDisksClientImpl);
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A stub implementaion of CrosDisksClient.
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class CrosDisksClientStubImpl : public CrosDisksClient {
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
3792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CrosDisksClientStubImpl()
380c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      : weak_ptr_factory_(this) {}
3812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~CrosDisksClientStubImpl() {}
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // CrosDisksClient overrides:
385424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  virtual void Init(dbus::Bus* bus) OVERRIDE {}
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void Mount(const std::string& source_path,
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     const std::string& source_format,
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     const std::string& mount_label,
3897dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                     const base::Closure& callback,
3907dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                     const base::Closure& error_callback) OVERRIDE {
3912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // This stub implementation only accepts archive mount requests.
3927dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    const MountType type = MOUNT_TYPE_ARCHIVE;
3932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const base::FilePath mounted_path = GetArchiveMountPoint().Append(
3952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        base::FilePath::FromUTF8Unsafe(mount_label));
3962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Already mounted path.
3982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (mounted_to_source_path_map_.count(mounted_path.value()) != 0) {
3992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      FinishMount(MOUNT_ERROR_PATH_ALREADY_MOUNTED, source_path, type,
4002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                  std::string(), callback);
4012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return;
4022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
4032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Perform fake mount.
4052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::PostTaskAndReplyWithResult(
4067d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        base::WorkerPool::GetTaskRunner(true /* task_is_slow */).get(),
4072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        FROM_HERE,
4087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        base::Bind(&PerformFakeMount, source_path, mounted_path),
4092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        base::Bind(&CrosDisksClientStubImpl::ContinueMount,
4102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   weak_ptr_factory_.GetWeakPtr(),
4112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   source_path,
4122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   type,
4132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   callback,
4142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   mounted_path));
4152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void Unmount(const std::string& device_path,
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       UnmountOptions options,
419eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                       const base::Closure& callback,
420eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                       const base::Closure& error_callback) OVERRIDE {
4212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Not mounted.
4222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (mounted_to_source_path_map_.count(device_path) == 0) {
423eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      base::MessageLoopProxy::current()->PostTask(FROM_HERE, error_callback);
4242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return;
4252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
4262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    mounted_to_source_path_map_.erase(device_path);
4282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Remove the directory created in Mount().
4302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::WorkerPool::PostTaskAndReply(
4312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        FROM_HERE,
4327dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        base::Bind(base::IgnoreResult(&base::DeleteFile),
4332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   base::FilePath::FromUTF8Unsafe(device_path),
4342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   true /* recursive */),
435eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        callback,
4362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        true /* task_is_slow */);
4372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void EnumerateAutoMountableDevices(
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const EnumerateAutoMountableDevicesCallback& callback,
4417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      const base::Closure& error_callback) OVERRIDE {
4422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::vector<std::string> device_paths;
4432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::MessageLoopProxy::current()->PostTask(
4442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        FROM_HERE, base::Bind(callback, device_paths));
4452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void FormatDevice(const std::string& device_path,
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            const std::string& filesystem,
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            const FormatDeviceCallback& callback,
4507dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                            const base::Closure& error_callback) OVERRIDE {
4512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::MessageLoopProxy::current()->PostTask(FROM_HERE, error_callback);
4522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void GetDeviceProperties(
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const std::string& device_path,
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const GetDevicePropertiesCallback& callback,
4577dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      const base::Closure& error_callback) OVERRIDE {
4582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::MessageLoopProxy::current()->PostTask(FROM_HERE, error_callback);
4592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void SetUpConnections(
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const MountEventHandler& mount_event_handler,
4632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const MountCompletedHandler& mount_completed_handler) OVERRIDE {
4642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    mount_event_handler_ = mount_event_handler;
4652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    mount_completed_handler_ = mount_completed_handler;
4662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
4692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Performs file actions for Mount().
4702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static MountError PerformFakeMount(const std::string& source_path,
4712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                     const base::FilePath& mounted_path) {
4722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Check the source path exists.
4737dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    if (!base::PathExists(base::FilePath::FromUTF8Unsafe(source_path))) {
4742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      DLOG(ERROR) << "Source does not exist at " << source_path;
4752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return MOUNT_ERROR_INVALID_PATH;
4762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
4772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Just create an empty directory and shows it as the mounted directory.
4792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!file_util::CreateDirectory(mounted_path)) {
4802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      DLOG(ERROR) << "Failed to create directory at " << mounted_path.value();
4812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return MOUNT_ERROR_DIRECTORY_CREATION_FAILED;
4822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
4832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Put a dummy file.
4852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const base::FilePath dummy_file_path =
4862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        mounted_path.Append("SUCCESSFULLY_PERFORMED_FAKE_MOUNT.txt");
4872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string dummy_file_content = "This is a dummy file.";
4882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const int write_result = file_util::WriteFile(
4892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        dummy_file_path, dummy_file_content.data(), dummy_file_content.size());
4902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (write_result != static_cast<int>(dummy_file_content.size())) {
4912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      DLOG(ERROR) << "Failed to put a dummy file at "
4922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                  << dummy_file_path.value();
4932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return MOUNT_ERROR_MOUNT_PROGRAM_FAILED;
4942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
4952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return MOUNT_ERROR_NONE;
4972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Part of Mount() implementation.
5002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void ContinueMount(const std::string& source_path,
5012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                     MountType type,
5027dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                     const base::Closure& callback,
5032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                     const base::FilePath& mounted_path,
5042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                     MountError mount_error) {
5052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (mount_error != MOUNT_ERROR_NONE) {
5062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      FinishMount(mount_error, source_path, type, std::string(), callback);
5072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return;
5082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
5092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    mounted_to_source_path_map_[mounted_path.value()] = source_path;
5102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    FinishMount(MOUNT_ERROR_NONE, source_path, type,
5112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                mounted_path.AsUTF8Unsafe(), callback);
5122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Runs |callback| and sends MountCompleted signal.
5152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Part of Mount() implementation.
5162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void FinishMount(MountError error,
5172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   const std::string& source_path,
5182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   MountType type,
5192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   const std::string& mounted_path,
5207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                   const base::Closure& callback) {
5212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::MessageLoopProxy::current()->PostTask(FROM_HERE, callback);
5222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!mount_completed_handler_.is_null()) {
5232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::MessageLoopProxy::current()->PostTask(
5242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          FROM_HERE,
5252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          base::Bind(mount_completed_handler_,
5262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                     error, source_path, type, mounted_path));
5272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
5282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Mounted path to source path map.
5312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::map<std::string, std::string> mounted_to_source_path_map_;
5322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MountEventHandler mount_event_handler_;
5342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MountCompletedHandler mount_completed_handler_;
5352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::WeakPtrFactory<CrosDisksClientStubImpl> weak_ptr_factory_;
5372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(CrosDisksClientStubImpl);
5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// DiskInfo
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DiskInfo::DiskInfo(const std::string& device_path, dbus::Response* response)
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : device_path_(device_path),
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      is_drive_(false),
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      has_media_(false),
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      on_boot_device_(false),
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      device_type_(DEVICE_TYPE_UNKNOWN),
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      total_size_in_bytes_(0),
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      is_read_only_(false),
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      is_hidden_(true) {
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  InitializeFromResponse(response);
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DiskInfo::~DiskInfo() {
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Initializes |this| from |response| given by the cros-disks service.
5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Below is an example of |response|'s raw message (long string is ellipsized).
5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// message_type: MESSAGE_METHOD_RETURN
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// destination: :1.8
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// sender: :1.16
5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// signature: a{sv}
5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// serial: 96
5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// reply_serial: 267
5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// array [
5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   dict entry {
5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     string "DeviceFile"
5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     variant       string "/dev/sdb"
5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   }
5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   dict entry {
5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     string "DeviceIsDrive"
5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     variant       bool true
5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   }
5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   dict entry {
5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     string "DeviceIsMediaAvailable"
5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     variant       bool true
5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   }
5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   dict entry {
5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     string "DeviceIsMounted"
5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     variant       bool false
5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   }
5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   dict entry {
5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     string "DeviceIsOnBootDevice"
5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     variant       bool false
5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   }
5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   dict entry {
5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     string "DeviceIsReadOnly"
5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     variant       bool false
5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   }
5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   dict entry {
5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     string "DeviceIsVirtual"
5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     variant       bool false
6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   }
6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   dict entry {
6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     string "DeviceMediaType"
6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     variant       uint32 1
6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   }
6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   dict entry {
6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     string "DeviceMountPaths"
6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     variant       array [
6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//       ]
6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   }
6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   dict entry {
6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     string "DevicePresentationHide"
6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     variant       bool true
6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   }
6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   dict entry {
6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     string "DeviceSize"
6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     variant       uint64 7998537728
6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   }
6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   dict entry {
6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     string "DriveIsRotational"
6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     variant       bool false
6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   }
6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   dict entry {
6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     string "VendorId"
6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     variant       string "18d1"
6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   }
6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   dict entry {
6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     string "VendorName"
6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     variant       string "Google Inc."
6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   }
6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   dict entry {
6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     string "ProductId"
6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     variant       string "4e11"
6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   }
6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   dict entry {
6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     string "ProductName"
6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     variant       string "Nexus One"
6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   }
6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   dict entry {
6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     string "DriveModel"
6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     variant       string "TransMemory"
6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   }
6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   dict entry {
6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     string "IdLabel"
6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     variant       string ""
6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   }
6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   dict entry {
6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     string "IdUuid"
6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     variant       string ""
6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   }
6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   dict entry {
6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     string "NativePath"
6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     variant       string "/sys/devices/pci0000:00/0000:00:1d.7/usb1/1-4/...
6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   }
6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ]
6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DiskInfo::InitializeFromResponse(dbus::Response* response) {
6567dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  dbus::MessageReader reader(response);
6577dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  scoped_ptr<base::Value> value(dbus::PopDataAsValue(&reader));
6587dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  base::DictionaryValue* properties = NULL;
6597dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (!value || !value->GetAsDictionary(&properties))
6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6627dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  properties->GetBooleanWithoutPathExpansion(
6637dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      cros_disks::kDeviceIsDrive, &is_drive_);
6647dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  properties->GetBooleanWithoutPathExpansion(
6657dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      cros_disks::kDeviceIsReadOnly, &is_read_only_);
6667dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  properties->GetBooleanWithoutPathExpansion(
6677dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      cros_disks::kDevicePresentationHide, &is_hidden_);
6687dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  properties->GetBooleanWithoutPathExpansion(
6697dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      cros_disks::kDeviceIsMediaAvailable, &has_media_);
6707dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  properties->GetBooleanWithoutPathExpansion(
6717dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      cros_disks::kDeviceIsOnBootDevice, &on_boot_device_);
6727dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  properties->GetStringWithoutPathExpansion(
6737dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      cros_disks::kNativePath, &system_path_);
6747dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  properties->GetStringWithoutPathExpansion(
6757dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      cros_disks::kDeviceFile, &file_path_);
6767dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  properties->GetStringWithoutPathExpansion(cros_disks::kVendorId, &vendor_id_);
6777dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  properties->GetStringWithoutPathExpansion(
6787dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      cros_disks::kVendorName, &vendor_name_);
6797dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  properties->GetStringWithoutPathExpansion(
6807dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      cros_disks::kProductId, &product_id_);
6817dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  properties->GetStringWithoutPathExpansion(
6827dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      cros_disks::kProductName, &product_name_);
6837dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  properties->GetStringWithoutPathExpansion(
6847dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      cros_disks::kDriveModel, &drive_model_);
6857dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  properties->GetStringWithoutPathExpansion(cros_disks::kIdLabel, &label_);
6867dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  properties->GetStringWithoutPathExpansion(cros_disks::kIdUuid, &uuid_);
6877dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
6887dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // dbus::PopDataAsValue() pops uint64 as double.
6897dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // The top 11 bits of uint64 are dropped by the use of double. But, this works
6907dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // unless the size exceeds 8 PB.
6917dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  double device_size_double = 0;
6927dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (properties->GetDoubleWithoutPathExpansion(cros_disks::kDeviceSize,
6937dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                                                &device_size_double))
6947dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    total_size_in_bytes_ = device_size_double;
6957dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
6967dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // dbus::PopDataAsValue() pops uint32 as double.
6977dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  double media_type_double = 0;
6987dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (properties->GetDoubleWithoutPathExpansion(cros_disks::kDeviceMediaType,
6997dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                                                &media_type_double))
7007dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    device_type_ = DeviceMediaTypeToDeviceType(media_type_double);
7017dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
7027dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  base::ListValue* mount_paths = NULL;
7037dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (properties->GetListWithoutPathExpansion(cros_disks::kDeviceMountPaths,
7047dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                                              &mount_paths))
7057dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    mount_paths->GetString(0, &mount_path_);
7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// CrosDisksClient
7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CrosDisksClient::CrosDisksClient() {}
7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CrosDisksClient::~CrosDisksClient() {}
7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
716424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)CrosDisksClient* CrosDisksClient::Create(DBusClientImplementationType type) {
7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (type == REAL_DBUS_CLIENT_IMPLEMENTATION)
718424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    return new CrosDisksClientImpl();
7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_EQ(STUB_DBUS_CLIENT_IMPLEMENTATION, type);
7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return new CrosDisksClientStubImpl();
7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static
7242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)base::FilePath CrosDisksClient::GetArchiveMountPoint() {
7252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return base::FilePath(base::chromeos::IsRunningOnChromeOS() ?
7262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                        FILE_PATH_LITERAL("/media/archive") :
7272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                        FILE_PATH_LITERAL("/tmp/chromeos/media/archive"));
7282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
7292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static
7312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)base::FilePath CrosDisksClient::GetRemovableDiskMountPoint() {
7322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return base::FilePath(base::chromeos::IsRunningOnChromeOS() ?
7332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                        FILE_PATH_LITERAL("/media/removable") :
7342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                        FILE_PATH_LITERAL("/tmp/chromeos/media/removable"));
7352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
7362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace chromeos
738