blob: 4514030cfcc6fecb30fc81ccfc50f9f62ef29517 [file] [log] [blame]
Ryan Cairnsea6505f2011-04-10 19:54:53 -07001// Copyright (c) 2011 The Chromium OS 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
Ben Chan6e726922011-06-28 15:54:32 -07005#include "cros-disks/cros-disks-server-impl.h"
6
Ben Chanf51ff002011-04-25 12:41:57 -07007#include <base/logging.h>
Ben Chan6d0b2722011-11-18 08:24:14 -08008#include <chromeos/dbus/service_constants.h>
Ryan Cairnsea6505f2011-04-10 19:54:53 -07009
Ben Chan8dcede82011-07-25 20:56:13 -070010#include "cros-disks/archive-manager.h"
Ben Chan6e726922011-06-28 15:54:32 -070011#include "cros-disks/device-event.h"
Ben Chanbdc39742011-05-11 17:51:26 -070012#include "cros-disks/disk.h"
13#include "cros-disks/disk-manager.h"
Szymon Sidor2733b512011-06-30 18:00:51 -070014#include "cros-disks/format-manager.h"
Ben Chan8dcede82011-07-25 20:56:13 -070015#include "cros-disks/platform.h"
Szymon Sidor2733b512011-06-30 18:00:51 -070016
Ben Chan190d3cf2011-07-07 09:38:48 -070017using std::string;
18using std::vector;
Ryan Cairnsea6505f2011-04-10 19:54:53 -070019
Ben Chan460439f2011-09-13 09:16:28 -070020namespace cros_disks {
Ryan Cairnsea6505f2011-04-10 19:54:53 -070021
Ben Chan6e726922011-06-28 15:54:32 -070022CrosDisksServer::CrosDisksServer(DBus::Connection& connection, // NOLINT
Ben Chan8dcede82011-07-25 20:56:13 -070023 Platform* platform,
24 ArchiveManager* archive_manager,
25 DiskManager* disk_manager,
26 FormatManager* format_manager)
Ben Chan6d0b2722011-11-18 08:24:14 -080027 : DBus::ObjectAdaptor(connection, kCrosDisksServicePath),
Ben Chan8dcede82011-07-25 20:56:13 -070028 platform_(platform),
29 archive_manager_(archive_manager),
Ben Chan6e726922011-06-28 15:54:32 -070030 disk_manager_(disk_manager),
Ben Chan89cf29e2011-08-10 13:11:05 -070031 format_manager_(format_manager) {
Ben Chan8dcede82011-07-25 20:56:13 -070032 CHECK(platform_) << "Invalid platform object";
33 CHECK(archive_manager_) << "Invalid archive manager object";
Ben Chanb092d752011-07-13 11:44:38 -070034 CHECK(disk_manager_) << "Invalid disk manager object";
35 CHECK(format_manager_) << "Invalid format manager object";
Szymon Sidor2733b512011-06-30 18:00:51 -070036
Ben Chan8dcede82011-07-25 20:56:13 -070037 // TODO(benchan): Refactor the code so that we don't have to pass
38 // DiskManager, ArchiveManager, etc to the constructor
39 // of CrosDisksServer, but instead pass a list of mount
40 // managers.
41 mount_managers_.push_back(disk_manager_);
42 mount_managers_.push_back(archive_manager_);
43
Ben Chanb092d752011-07-13 11:44:38 -070044 InitializeProperties();
Szymon Sidor2733b512011-06-30 18:00:51 -070045 format_manager_->set_parent(this);
Ben Chanf51ff002011-04-25 12:41:57 -070046}
Ryan Cairnsea6505f2011-04-10 19:54:53 -070047
Ben Chan190d3cf2011-07-07 09:38:48 -070048CrosDisksServer::~CrosDisksServer() {
49}
Ryan Cairnsea6505f2011-04-10 19:54:53 -070050
51bool CrosDisksServer::IsAlive(DBus::Error& error) { // NOLINT
52 return true;
53}
54
Ben Chan190d3cf2011-07-07 09:38:48 -070055void CrosDisksServer::SignalFormattingFinished(const string& device_path,
Ben Chan8dcede82011-07-25 20:56:13 -070056 int status) {
Szymon Sidor2733b512011-06-30 18:00:51 -070057 if (status) {
Szymon Sidorea0ecbd32011-07-19 16:23:10 -070058 FormattingFinished(std::string("!") + device_path);
Szymon Sidor2733b512011-06-30 18:00:51 -070059 LOG(ERROR) << "Could not format device '" << device_path
Ben Chan8dcede82011-07-25 20:56:13 -070060 << "'. Formatting process failed with an exit code " << status;
Szymon Sidor2733b512011-06-30 18:00:51 -070061 } else {
Szymon Sidorea0ecbd32011-07-19 16:23:10 -070062 FormattingFinished(device_path);
Szymon Sidor2733b512011-06-30 18:00:51 -070063 }
64}
65
Ben Chan190d3cf2011-07-07 09:38:48 -070066bool CrosDisksServer::FormatDevice(const string& device_path,
Ben Chan8dcede82011-07-25 20:56:13 -070067 const string& filesystem,
68 DBus::Error &error) { // NOLINT
Szymon Sidor2733b512011-06-30 18:00:51 -070069 if (!format_manager_->StartFormatting(device_path, filesystem)) {
70 LOG(ERROR) << "Could not format device " << device_path
Ben Chan8dcede82011-07-25 20:56:13 -070071 << " as file system '" << filesystem << "'";
Szymon Sidor2733b512011-06-30 18:00:51 -070072 return false;
73 }
74 return true;
75}
76
Ben Chand3fdc722011-07-21 18:15:22 -070077void CrosDisksServer::Mount(const string& path,
Ben Chan8dcede82011-07-25 20:56:13 -070078 const string& filesystem_type,
79 const vector<string>& options,
80 DBus::Error& error) { // NOLINT
Ben Chanfcb2fc02011-11-21 09:44:07 -080081 MountErrorType error_type = MOUNT_ERROR_INVALID_PATH;
Ben Chan6d0b2722011-11-18 08:24:14 -080082 MountSourceType source_type = MOUNT_SOURCE_INVALID;
Ben Chand3fdc722011-07-21 18:15:22 -070083 string mount_path;
Ben Chan8dcede82011-07-25 20:56:13 -070084
85 for (vector<MountManager*>::iterator manager_iter = mount_managers_.begin();
86 manager_iter != mount_managers_.end(); ++manager_iter) {
87 MountManager* manager = *manager_iter;
88 if (manager->CanMount(path)) {
89 source_type = manager->GetMountSourceType();
90 error_type = manager->Mount(path, filesystem_type, options, &mount_path);
91 break;
92 }
93 }
94
Ben Chanfcb2fc02011-11-21 09:44:07 -080095 if (error_type != MOUNT_ERROR_NONE) {
Ben Chan8dcede82011-07-25 20:56:13 -070096 LOG(ERROR) << "Failed to mount '" << path << "'";
Ben Chand3fdc722011-07-21 18:15:22 -070097 }
Ben Chan8dcede82011-07-25 20:56:13 -070098 MountCompleted(error_type, path, source_type, mount_path);
Ben Chand3fdc722011-07-21 18:15:22 -070099}
100
101void CrosDisksServer::Unmount(const string& path,
Ben Chan8dcede82011-07-25 20:56:13 -0700102 const vector<string>& options,
103 DBus::Error& error) { // NOLINT
Ben Chanfcb2fc02011-11-21 09:44:07 -0800104 MountErrorType error_type = MOUNT_ERROR_INVALID_PATH;
Ben Chan8dcede82011-07-25 20:56:13 -0700105 for (vector<MountManager*>::iterator manager_iter = mount_managers_.begin();
106 manager_iter != mount_managers_.end(); ++manager_iter) {
107 MountManager* manager = *manager_iter;
108 if (manager->CanUnmount(path)) {
109 error_type = manager->Unmount(path, options);
110 break;
111 }
112 }
113
Ben Chanfcb2fc02011-11-21 09:44:07 -0800114 if (error_type != MOUNT_ERROR_NONE) {
Ben Chan8dcede82011-07-25 20:56:13 -0700115 string message = "Failed to unmount '" + path + "'";
Ben Chan6d0b2722011-11-18 08:24:14 -0800116 error.set(kCrosDisksServiceError, message.c_str());
Ben Chand3fdc722011-07-21 18:15:22 -0700117 }
118}
119
Ben Chan8f513762011-11-14 12:44:42 -0800120void CrosDisksServer::UnmountAll(DBus::Error& error) { // NOLINT
121 DoUnmountAll();
122}
123
124void CrosDisksServer::DoUnmountAll() {
125 for (vector<MountManager*>::iterator manager_iter = mount_managers_.begin();
126 manager_iter != mount_managers_.end(); ++manager_iter) {
127 MountManager* manager = *manager_iter;
128 manager->UnmountAll();
129 }
130}
131
Ben Chan190d3cf2011-07-07 09:38:48 -0700132vector<string> CrosDisksServer::DoEnumerateDevices(
Ben Chan490319f2011-05-06 14:00:42 -0700133 bool auto_mountable_only) const {
Ben Chan190d3cf2011-07-07 09:38:48 -0700134 vector<Disk> disks = disk_manager_->EnumerateDisks();
135 vector<string> devices;
Ben Chanf51ff002011-04-25 12:41:57 -0700136 devices.reserve(disks.size());
Ben Chan8dcede82011-07-25 20:56:13 -0700137 for (vector<Disk>::const_iterator disk_iterator = disks.begin();
138 disk_iterator != disks.end(); ++disk_iterator) {
Ben Chan1c2d4252011-06-03 13:33:49 -0700139 if (!auto_mountable_only || disk_iterator->is_auto_mountable()) {
Ben Chan490319f2011-05-06 14:00:42 -0700140 devices.push_back(disk_iterator->native_path());
141 }
142 }
Ben Chanf51ff002011-04-25 12:41:57 -0700143 return devices;
144}
145
Ben Chan190d3cf2011-07-07 09:38:48 -0700146vector<string> CrosDisksServer::EnumerateDevices(
Ben Chan490319f2011-05-06 14:00:42 -0700147 DBus::Error& error) { // NOLINT
148 return DoEnumerateDevices(false);
149}
150
Ben Chan190d3cf2011-07-07 09:38:48 -0700151vector<string> CrosDisksServer::EnumerateAutoMountableDevices(
Ben Chan490319f2011-05-06 14:00:42 -0700152 DBus::Error& error) { // NOLINT
153 return DoEnumerateDevices(true);
154}
155
Ben Chan190d3cf2011-07-07 09:38:48 -0700156DBusDisk CrosDisksServer::GetDeviceProperties(const string& device_path,
Ben Chan8dcede82011-07-25 20:56:13 -0700157 DBus::Error& error) { // NOLINT
Ben Chanf51ff002011-04-25 12:41:57 -0700158 Disk disk;
159 if (!disk_manager_->GetDiskByDevicePath(device_path, &disk)) {
Ben Chan190d3cf2011-07-07 09:38:48 -0700160 string message = "Could not get the properties of device " + device_path;
Ben Chanf51ff002011-04-25 12:41:57 -0700161 LOG(ERROR) << message;
Ben Chan6d0b2722011-11-18 08:24:14 -0800162 error.set(kCrosDisksServiceError, message.c_str());
Ben Chanf51ff002011-04-25 12:41:57 -0700163 }
164 return disk.ToDBusFormat();
165}
166
Ben Chan190d3cf2011-07-07 09:38:48 -0700167void CrosDisksServer::OnSessionStarted(const string& user) {
Ben Chan8dcede82011-07-25 20:56:13 -0700168 for (vector<MountManager*>::iterator manager_iter = mount_managers_.begin();
169 manager_iter != mount_managers_.end(); ++manager_iter) {
170 MountManager* manager = *manager_iter;
171 manager->StartSession(user);
172 }
Ben Chan6e726922011-06-28 15:54:32 -0700173}
174
Ben Chan190d3cf2011-07-07 09:38:48 -0700175void CrosDisksServer::OnSessionStopped(const string& user) {
Ben Chan8dcede82011-07-25 20:56:13 -0700176 for (vector<MountManager*>::iterator manager_iter = mount_managers_.begin();
177 manager_iter != mount_managers_.end(); ++manager_iter) {
178 MountManager* manager = *manager_iter;
179 manager->StopSession(user);
180 }
Ben Chan6e726922011-06-28 15:54:32 -0700181}
182
183void CrosDisksServer::DispatchDeviceEvent(const DeviceEvent& event) {
184 switch (event.event_type) {
185 case DeviceEvent::kDeviceAdded:
186 DeviceAdded(event.device_path);
187 break;
188 case DeviceEvent::kDeviceScanned:
189 DeviceScanned(event.device_path);
190 break;
191 case DeviceEvent::kDeviceRemoved:
192 DeviceRemoved(event.device_path);
193 break;
194 case DeviceEvent::kDiskAdded:
195 DiskAdded(event.device_path);
196 break;
197 case DeviceEvent::kDiskAddedAfterRemoved:
198 DiskRemoved(event.device_path);
199 DiskAdded(event.device_path);
200 break;
201 case DeviceEvent::kDiskChanged:
202 DiskChanged(event.device_path);
203 break;
204 case DeviceEvent::kDiskRemoved:
205 DiskRemoved(event.device_path);
206 break;
207 default:
208 break;
209 }
210}
211
Ben Chanb092d752011-07-13 11:44:38 -0700212void CrosDisksServer::InitializeProperties() {
213 try {
214 DBus::Variant value;
Ben Chan8dcede82011-07-25 20:56:13 -0700215 value.writer().append_bool(platform_->experimental_features_enabled());
Ben Chan6d0b2722011-11-18 08:24:14 -0800216 CrosDisks_adaptor::set_property(kExperimentalFeaturesEnabled, value);
Ben Chan8dcede82011-07-25 20:56:13 -0700217 } catch (const DBus::Error& e) { // NOLINT
Ben Chanb092d752011-07-13 11:44:38 -0700218 LOG(FATAL) << "Failed to initialize properties: " << e.what();
219 }
220}
221
222void CrosDisksServer::on_set_property(
223 DBus::InterfaceAdaptor& interface, // NOLINT
Ben Chan8dcede82011-07-25 20:56:13 -0700224 const string& property, const DBus::Variant& value) {
Ben Chan6d0b2722011-11-18 08:24:14 -0800225 if (property == kExperimentalFeaturesEnabled) {
Ben Chan8dcede82011-07-25 20:56:13 -0700226 platform_->set_experimental_features_enabled(value.reader().get_bool());
Ben Chanb092d752011-07-13 11:44:38 -0700227 }
228}
229
Ben Chanbdc39742011-05-11 17:51:26 -0700230} // namespace cros_disks