blob: 6e4e391a5b5337f020707bac05d23ad42a29ae7e [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();
Ben Chanc1e766c2011-11-21 12:56:59 -080045 format_manager_->set_observer(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 Chanc1e766c2011-11-21 12:56:59 -080055void CrosDisksServer::Format(const string& path,
56 const string& filesystem_type,
57 const vector<string>& options,
58 DBus::Error &error) { // NOLINT
59 FormatDevice(path, filesystem_type, error);
Szymon Sidor2733b512011-06-30 18:00:51 -070060}
61
Ben Chanc1e766c2011-11-21 12:56:59 -080062// TODO(benchan): Remove this method after Chrome switches to use Format().
63bool CrosDisksServer::FormatDevice(const string& path,
64 const string& filesystem_type,
Ben Chan8dcede82011-07-25 20:56:13 -070065 DBus::Error &error) { // NOLINT
Ben Chanc833a522012-09-27 23:47:00 -070066 FormatErrorType error_type = FORMAT_ERROR_NONE;
67 Disk disk;
68 if (!disk_manager_->GetDiskByDevicePath(path, &disk)) {
69 error_type = FORMAT_ERROR_INVALID_DEVICE_PATH;
70 } else if (disk.is_on_boot_device()) {
71 error_type = FORMAT_ERROR_DEVICE_NOT_ALLOWED;
72 } else {
Toni Barzic031dc712012-11-20 18:15:46 -080073 error_type =
74 format_manager_->StartFormatting(disk.device_file(), filesystem_type);
Ben Chanc833a522012-09-27 23:47:00 -070075 }
76
Ben Chanc1e766c2011-11-21 12:56:59 -080077 if (error_type != FORMAT_ERROR_NONE) {
78 LOG(ERROR) << "Could not format device '" << path
79 << "' as filesystem '" << filesystem_type << "'";
80 FormatCompleted(error_type, path);
Szymon Sidor2733b512011-06-30 18:00:51 -070081 return false;
82 }
83 return true;
84}
85
Ben Chand3fdc722011-07-21 18:15:22 -070086void CrosDisksServer::Mount(const string& path,
Ben Chan8dcede82011-07-25 20:56:13 -070087 const string& filesystem_type,
88 const vector<string>& options,
89 DBus::Error& error) { // NOLINT
Ben Chanfcb2fc02011-11-21 09:44:07 -080090 MountErrorType error_type = MOUNT_ERROR_INVALID_PATH;
Ben Chan6d0b2722011-11-18 08:24:14 -080091 MountSourceType source_type = MOUNT_SOURCE_INVALID;
Ben Chand3fdc722011-07-21 18:15:22 -070092 string mount_path;
Ben Chan8dcede82011-07-25 20:56:13 -070093
94 for (vector<MountManager*>::iterator manager_iter = mount_managers_.begin();
95 manager_iter != mount_managers_.end(); ++manager_iter) {
96 MountManager* manager = *manager_iter;
97 if (manager->CanMount(path)) {
98 source_type = manager->GetMountSourceType();
99 error_type = manager->Mount(path, filesystem_type, options, &mount_path);
100 break;
101 }
102 }
103
Ben Chanfcb2fc02011-11-21 09:44:07 -0800104 if (error_type != MOUNT_ERROR_NONE) {
Ben Chan8dcede82011-07-25 20:56:13 -0700105 LOG(ERROR) << "Failed to mount '" << path << "'";
Ben Chand3fdc722011-07-21 18:15:22 -0700106 }
Ben Chan8dcede82011-07-25 20:56:13 -0700107 MountCompleted(error_type, path, source_type, mount_path);
Ben Chand3fdc722011-07-21 18:15:22 -0700108}
109
110void CrosDisksServer::Unmount(const string& path,
Ben Chan8dcede82011-07-25 20:56:13 -0700111 const vector<string>& options,
112 DBus::Error& error) { // NOLINT
Ben Chanfcb2fc02011-11-21 09:44:07 -0800113 MountErrorType error_type = MOUNT_ERROR_INVALID_PATH;
Ben Chan8dcede82011-07-25 20:56:13 -0700114 for (vector<MountManager*>::iterator manager_iter = mount_managers_.begin();
115 manager_iter != mount_managers_.end(); ++manager_iter) {
116 MountManager* manager = *manager_iter;
117 if (manager->CanUnmount(path)) {
118 error_type = manager->Unmount(path, options);
119 break;
120 }
121 }
122
Ben Chanfcb2fc02011-11-21 09:44:07 -0800123 if (error_type != MOUNT_ERROR_NONE) {
Ben Chan8dcede82011-07-25 20:56:13 -0700124 string message = "Failed to unmount '" + path + "'";
Ben Chan6d0b2722011-11-18 08:24:14 -0800125 error.set(kCrosDisksServiceError, message.c_str());
Ben Chand3fdc722011-07-21 18:15:22 -0700126 }
127}
128
Ben Chan8f513762011-11-14 12:44:42 -0800129void CrosDisksServer::UnmountAll(DBus::Error& error) { // NOLINT
130 DoUnmountAll();
131}
132
133void CrosDisksServer::DoUnmountAll() {
134 for (vector<MountManager*>::iterator manager_iter = mount_managers_.begin();
135 manager_iter != mount_managers_.end(); ++manager_iter) {
136 MountManager* manager = *manager_iter;
137 manager->UnmountAll();
138 }
139}
140
Ben Chan190d3cf2011-07-07 09:38:48 -0700141vector<string> CrosDisksServer::DoEnumerateDevices(
Ben Chan490319f2011-05-06 14:00:42 -0700142 bool auto_mountable_only) const {
Ben Chan190d3cf2011-07-07 09:38:48 -0700143 vector<Disk> disks = disk_manager_->EnumerateDisks();
144 vector<string> devices;
Ben Chanf51ff002011-04-25 12:41:57 -0700145 devices.reserve(disks.size());
Ben Chan8dcede82011-07-25 20:56:13 -0700146 for (vector<Disk>::const_iterator disk_iterator = disks.begin();
147 disk_iterator != disks.end(); ++disk_iterator) {
Ben Chan1c2d4252011-06-03 13:33:49 -0700148 if (!auto_mountable_only || disk_iterator->is_auto_mountable()) {
Ben Chan490319f2011-05-06 14:00:42 -0700149 devices.push_back(disk_iterator->native_path());
150 }
151 }
Ben Chanf51ff002011-04-25 12:41:57 -0700152 return devices;
153}
154
Ben Chan190d3cf2011-07-07 09:38:48 -0700155vector<string> CrosDisksServer::EnumerateDevices(
Ben Chan490319f2011-05-06 14:00:42 -0700156 DBus::Error& error) { // NOLINT
157 return DoEnumerateDevices(false);
158}
159
Ben Chan190d3cf2011-07-07 09:38:48 -0700160vector<string> CrosDisksServer::EnumerateAutoMountableDevices(
Ben Chan490319f2011-05-06 14:00:42 -0700161 DBus::Error& error) { // NOLINT
162 return DoEnumerateDevices(true);
163}
164
Ben Chan190d3cf2011-07-07 09:38:48 -0700165DBusDisk CrosDisksServer::GetDeviceProperties(const string& device_path,
Ben Chan8dcede82011-07-25 20:56:13 -0700166 DBus::Error& error) { // NOLINT
Ben Chanf51ff002011-04-25 12:41:57 -0700167 Disk disk;
168 if (!disk_manager_->GetDiskByDevicePath(device_path, &disk)) {
Ben Chan190d3cf2011-07-07 09:38:48 -0700169 string message = "Could not get the properties of device " + device_path;
Ben Chanf51ff002011-04-25 12:41:57 -0700170 LOG(ERROR) << message;
Ben Chan6d0b2722011-11-18 08:24:14 -0800171 error.set(kCrosDisksServiceError, message.c_str());
Ben Chanf51ff002011-04-25 12:41:57 -0700172 }
173 return disk.ToDBusFormat();
174}
175
Ben Chanc1e766c2011-11-21 12:56:59 -0800176void CrosDisksServer::OnFormatCompleted(const string& device_path,
177 FormatErrorType error_type) {
178 // TODO(benchan): Deprecate the FormattingFinished signal once Chrome
179 // switches to observe the FormatCompleted signal instead.
180 if (error_type != FORMAT_ERROR_NONE) {
181 FormattingFinished("!" + device_path);
182 LOG(ERROR) << "Failed to format '" << device_path << "'";
183 } else {
184 FormattingFinished(device_path);
185 }
186 FormatCompleted(error_type, device_path);
187}
188
Ben Chan5988f292012-09-18 08:32:42 -0700189void CrosDisksServer::OnScreenIsLocked() {
190 // no-op
191}
192
193void CrosDisksServer::OnScreenIsUnlocked() {
194 // no-op
195}
196
Ben Chanb3bf8d12013-04-23 13:57:55 -0700197void CrosDisksServer::OnSessionStarted() {
Ben Chan8dcede82011-07-25 20:56:13 -0700198 for (vector<MountManager*>::iterator manager_iter = mount_managers_.begin();
199 manager_iter != mount_managers_.end(); ++manager_iter) {
200 MountManager* manager = *manager_iter;
Ben Chanb3bf8d12013-04-23 13:57:55 -0700201 manager->StartSession();
Ben Chan8dcede82011-07-25 20:56:13 -0700202 }
Ben Chan6e726922011-06-28 15:54:32 -0700203}
204
Ben Chanb3bf8d12013-04-23 13:57:55 -0700205void CrosDisksServer::OnSessionStopped() {
Ben Chan8dcede82011-07-25 20:56:13 -0700206 for (vector<MountManager*>::iterator manager_iter = mount_managers_.begin();
207 manager_iter != mount_managers_.end(); ++manager_iter) {
208 MountManager* manager = *manager_iter;
Ben Chanb3bf8d12013-04-23 13:57:55 -0700209 manager->StopSession();
Ben Chan8dcede82011-07-25 20:56:13 -0700210 }
Ben Chan6e726922011-06-28 15:54:32 -0700211}
212
213void CrosDisksServer::DispatchDeviceEvent(const DeviceEvent& event) {
214 switch (event.event_type) {
215 case DeviceEvent::kDeviceAdded:
216 DeviceAdded(event.device_path);
217 break;
218 case DeviceEvent::kDeviceScanned:
219 DeviceScanned(event.device_path);
220 break;
221 case DeviceEvent::kDeviceRemoved:
222 DeviceRemoved(event.device_path);
223 break;
224 case DeviceEvent::kDiskAdded:
225 DiskAdded(event.device_path);
226 break;
Ben Chan6e726922011-06-28 15:54:32 -0700227 case DeviceEvent::kDiskChanged:
228 DiskChanged(event.device_path);
229 break;
230 case DeviceEvent::kDiskRemoved:
231 DiskRemoved(event.device_path);
232 break;
233 default:
234 break;
235 }
236}
237
Ben Chanb092d752011-07-13 11:44:38 -0700238void CrosDisksServer::InitializeProperties() {
239 try {
240 DBus::Variant value;
Ben Chan8dcede82011-07-25 20:56:13 -0700241 value.writer().append_bool(platform_->experimental_features_enabled());
Ben Chan6d0b2722011-11-18 08:24:14 -0800242 CrosDisks_adaptor::set_property(kExperimentalFeaturesEnabled, value);
Ben Chan8dcede82011-07-25 20:56:13 -0700243 } catch (const DBus::Error& e) { // NOLINT
Ben Chanb092d752011-07-13 11:44:38 -0700244 LOG(FATAL) << "Failed to initialize properties: " << e.what();
245 }
246}
247
248void CrosDisksServer::on_set_property(
249 DBus::InterfaceAdaptor& interface, // NOLINT
Ben Chan8dcede82011-07-25 20:56:13 -0700250 const string& property, const DBus::Variant& value) {
Ben Chan6d0b2722011-11-18 08:24:14 -0800251 if (property == kExperimentalFeaturesEnabled) {
Ben Chan8dcede82011-07-25 20:56:13 -0700252 platform_->set_experimental_features_enabled(value.reader().get_bool());
Ben Chanb092d752011-07-13 11:44:38 -0700253 }
254}
255
Ben Chanbdc39742011-05-11 17:51:26 -0700256} // namespace cros_disks