Ryan Cairns | ea6505f | 2011-04-10 19:54:53 -0700 | [diff] [blame] | 1 | // 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 Chan | 6e72692 | 2011-06-28 15:54:32 -0700 | [diff] [blame] | 5 | #include "cros-disks/cros-disks-server-impl.h" |
| 6 | |
Ben Chan | f51ff00 | 2011-04-25 12:41:57 -0700 | [diff] [blame] | 7 | #include <base/logging.h> |
Ben Chan | 6d0b272 | 2011-11-18 08:24:14 -0800 | [diff] [blame] | 8 | #include <chromeos/dbus/service_constants.h> |
Ryan Cairns | ea6505f | 2011-04-10 19:54:53 -0700 | [diff] [blame] | 9 | |
Ben Chan | 8dcede8 | 2011-07-25 20:56:13 -0700 | [diff] [blame] | 10 | #include "cros-disks/archive-manager.h" |
Ben Chan | 6e72692 | 2011-06-28 15:54:32 -0700 | [diff] [blame] | 11 | #include "cros-disks/device-event.h" |
Ben Chan | bdc3974 | 2011-05-11 17:51:26 -0700 | [diff] [blame] | 12 | #include "cros-disks/disk.h" |
| 13 | #include "cros-disks/disk-manager.h" |
Szymon Sidor | 2733b51 | 2011-06-30 18:00:51 -0700 | [diff] [blame] | 14 | #include "cros-disks/format-manager.h" |
Ben Chan | 8dcede8 | 2011-07-25 20:56:13 -0700 | [diff] [blame] | 15 | #include "cros-disks/platform.h" |
Szymon Sidor | 2733b51 | 2011-06-30 18:00:51 -0700 | [diff] [blame] | 16 | |
Ben Chan | 190d3cf | 2011-07-07 09:38:48 -0700 | [diff] [blame] | 17 | using std::string; |
| 18 | using std::vector; |
Ryan Cairns | ea6505f | 2011-04-10 19:54:53 -0700 | [diff] [blame] | 19 | |
Ben Chan | 460439f | 2011-09-13 09:16:28 -0700 | [diff] [blame] | 20 | namespace cros_disks { |
Ryan Cairns | ea6505f | 2011-04-10 19:54:53 -0700 | [diff] [blame] | 21 | |
Ben Chan | 6e72692 | 2011-06-28 15:54:32 -0700 | [diff] [blame] | 22 | CrosDisksServer::CrosDisksServer(DBus::Connection& connection, // NOLINT |
Ben Chan | 8dcede8 | 2011-07-25 20:56:13 -0700 | [diff] [blame] | 23 | Platform* platform, |
| 24 | ArchiveManager* archive_manager, |
| 25 | DiskManager* disk_manager, |
| 26 | FormatManager* format_manager) |
Ben Chan | 6d0b272 | 2011-11-18 08:24:14 -0800 | [diff] [blame] | 27 | : DBus::ObjectAdaptor(connection, kCrosDisksServicePath), |
Ben Chan | 8dcede8 | 2011-07-25 20:56:13 -0700 | [diff] [blame] | 28 | platform_(platform), |
| 29 | archive_manager_(archive_manager), |
Ben Chan | 6e72692 | 2011-06-28 15:54:32 -0700 | [diff] [blame] | 30 | disk_manager_(disk_manager), |
Ben Chan | 89cf29e | 2011-08-10 13:11:05 -0700 | [diff] [blame] | 31 | format_manager_(format_manager) { |
Ben Chan | 8dcede8 | 2011-07-25 20:56:13 -0700 | [diff] [blame] | 32 | CHECK(platform_) << "Invalid platform object"; |
| 33 | CHECK(archive_manager_) << "Invalid archive manager object"; |
Ben Chan | b092d75 | 2011-07-13 11:44:38 -0700 | [diff] [blame] | 34 | CHECK(disk_manager_) << "Invalid disk manager object"; |
| 35 | CHECK(format_manager_) << "Invalid format manager object"; |
Szymon Sidor | 2733b51 | 2011-06-30 18:00:51 -0700 | [diff] [blame] | 36 | |
Ben Chan | 8dcede8 | 2011-07-25 20:56:13 -0700 | [diff] [blame] | 37 | // 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 Chan | b092d75 | 2011-07-13 11:44:38 -0700 | [diff] [blame] | 44 | InitializeProperties(); |
Ben Chan | c1e766c | 2011-11-21 12:56:59 -0800 | [diff] [blame] | 45 | format_manager_->set_observer(this); |
Ben Chan | f51ff00 | 2011-04-25 12:41:57 -0700 | [diff] [blame] | 46 | } |
Ryan Cairns | ea6505f | 2011-04-10 19:54:53 -0700 | [diff] [blame] | 47 | |
Ben Chan | 190d3cf | 2011-07-07 09:38:48 -0700 | [diff] [blame] | 48 | CrosDisksServer::~CrosDisksServer() { |
| 49 | } |
Ryan Cairns | ea6505f | 2011-04-10 19:54:53 -0700 | [diff] [blame] | 50 | |
| 51 | bool CrosDisksServer::IsAlive(DBus::Error& error) { // NOLINT |
| 52 | return true; |
| 53 | } |
| 54 | |
Ben Chan | c1e766c | 2011-11-21 12:56:59 -0800 | [diff] [blame] | 55 | void 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 Sidor | 2733b51 | 2011-06-30 18:00:51 -0700 | [diff] [blame] | 60 | } |
| 61 | |
Ben Chan | c1e766c | 2011-11-21 12:56:59 -0800 | [diff] [blame] | 62 | // TODO(benchan): Remove this method after Chrome switches to use Format(). |
| 63 | bool CrosDisksServer::FormatDevice(const string& path, |
| 64 | const string& filesystem_type, |
Ben Chan | 8dcede8 | 2011-07-25 20:56:13 -0700 | [diff] [blame] | 65 | DBus::Error &error) { // NOLINT |
Ben Chan | c833a52 | 2012-09-27 23:47:00 -0700 | [diff] [blame] | 66 | 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 Barzic | 031dc71 | 2012-11-20 18:15:46 -0800 | [diff] [blame] | 73 | error_type = |
| 74 | format_manager_->StartFormatting(disk.device_file(), filesystem_type); |
Ben Chan | c833a52 | 2012-09-27 23:47:00 -0700 | [diff] [blame] | 75 | } |
| 76 | |
Ben Chan | c1e766c | 2011-11-21 12:56:59 -0800 | [diff] [blame] | 77 | 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 Sidor | 2733b51 | 2011-06-30 18:00:51 -0700 | [diff] [blame] | 81 | return false; |
| 82 | } |
| 83 | return true; |
| 84 | } |
| 85 | |
Ben Chan | d3fdc72 | 2011-07-21 18:15:22 -0700 | [diff] [blame] | 86 | void CrosDisksServer::Mount(const string& path, |
Ben Chan | 8dcede8 | 2011-07-25 20:56:13 -0700 | [diff] [blame] | 87 | const string& filesystem_type, |
| 88 | const vector<string>& options, |
| 89 | DBus::Error& error) { // NOLINT |
Ben Chan | fcb2fc0 | 2011-11-21 09:44:07 -0800 | [diff] [blame] | 90 | MountErrorType error_type = MOUNT_ERROR_INVALID_PATH; |
Ben Chan | 6d0b272 | 2011-11-18 08:24:14 -0800 | [diff] [blame] | 91 | MountSourceType source_type = MOUNT_SOURCE_INVALID; |
Ben Chan | d3fdc72 | 2011-07-21 18:15:22 -0700 | [diff] [blame] | 92 | string mount_path; |
Ben Chan | 8dcede8 | 2011-07-25 20:56:13 -0700 | [diff] [blame] | 93 | |
| 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 Chan | fcb2fc0 | 2011-11-21 09:44:07 -0800 | [diff] [blame] | 104 | if (error_type != MOUNT_ERROR_NONE) { |
Ben Chan | 8dcede8 | 2011-07-25 20:56:13 -0700 | [diff] [blame] | 105 | LOG(ERROR) << "Failed to mount '" << path << "'"; |
Ben Chan | d3fdc72 | 2011-07-21 18:15:22 -0700 | [diff] [blame] | 106 | } |
Ben Chan | 8dcede8 | 2011-07-25 20:56:13 -0700 | [diff] [blame] | 107 | MountCompleted(error_type, path, source_type, mount_path); |
Ben Chan | d3fdc72 | 2011-07-21 18:15:22 -0700 | [diff] [blame] | 108 | } |
| 109 | |
| 110 | void CrosDisksServer::Unmount(const string& path, |
Ben Chan | 8dcede8 | 2011-07-25 20:56:13 -0700 | [diff] [blame] | 111 | const vector<string>& options, |
| 112 | DBus::Error& error) { // NOLINT |
Ben Chan | fcb2fc0 | 2011-11-21 09:44:07 -0800 | [diff] [blame] | 113 | MountErrorType error_type = MOUNT_ERROR_INVALID_PATH; |
Ben Chan | 8dcede8 | 2011-07-25 20:56:13 -0700 | [diff] [blame] | 114 | 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 Chan | fcb2fc0 | 2011-11-21 09:44:07 -0800 | [diff] [blame] | 123 | if (error_type != MOUNT_ERROR_NONE) { |
Ben Chan | 8dcede8 | 2011-07-25 20:56:13 -0700 | [diff] [blame] | 124 | string message = "Failed to unmount '" + path + "'"; |
Ben Chan | 6d0b272 | 2011-11-18 08:24:14 -0800 | [diff] [blame] | 125 | error.set(kCrosDisksServiceError, message.c_str()); |
Ben Chan | d3fdc72 | 2011-07-21 18:15:22 -0700 | [diff] [blame] | 126 | } |
| 127 | } |
| 128 | |
Ben Chan | 8f51376 | 2011-11-14 12:44:42 -0800 | [diff] [blame] | 129 | void CrosDisksServer::UnmountAll(DBus::Error& error) { // NOLINT |
| 130 | DoUnmountAll(); |
| 131 | } |
| 132 | |
| 133 | void 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 Chan | 190d3cf | 2011-07-07 09:38:48 -0700 | [diff] [blame] | 141 | vector<string> CrosDisksServer::DoEnumerateDevices( |
Ben Chan | 490319f | 2011-05-06 14:00:42 -0700 | [diff] [blame] | 142 | bool auto_mountable_only) const { |
Ben Chan | 190d3cf | 2011-07-07 09:38:48 -0700 | [diff] [blame] | 143 | vector<Disk> disks = disk_manager_->EnumerateDisks(); |
| 144 | vector<string> devices; |
Ben Chan | f51ff00 | 2011-04-25 12:41:57 -0700 | [diff] [blame] | 145 | devices.reserve(disks.size()); |
Ben Chan | 8dcede8 | 2011-07-25 20:56:13 -0700 | [diff] [blame] | 146 | for (vector<Disk>::const_iterator disk_iterator = disks.begin(); |
| 147 | disk_iterator != disks.end(); ++disk_iterator) { |
Ben Chan | 1c2d425 | 2011-06-03 13:33:49 -0700 | [diff] [blame] | 148 | if (!auto_mountable_only || disk_iterator->is_auto_mountable()) { |
Ben Chan | 490319f | 2011-05-06 14:00:42 -0700 | [diff] [blame] | 149 | devices.push_back(disk_iterator->native_path()); |
| 150 | } |
| 151 | } |
Ben Chan | f51ff00 | 2011-04-25 12:41:57 -0700 | [diff] [blame] | 152 | return devices; |
| 153 | } |
| 154 | |
Ben Chan | 190d3cf | 2011-07-07 09:38:48 -0700 | [diff] [blame] | 155 | vector<string> CrosDisksServer::EnumerateDevices( |
Ben Chan | 490319f | 2011-05-06 14:00:42 -0700 | [diff] [blame] | 156 | DBus::Error& error) { // NOLINT |
| 157 | return DoEnumerateDevices(false); |
| 158 | } |
| 159 | |
Ben Chan | 190d3cf | 2011-07-07 09:38:48 -0700 | [diff] [blame] | 160 | vector<string> CrosDisksServer::EnumerateAutoMountableDevices( |
Ben Chan | 490319f | 2011-05-06 14:00:42 -0700 | [diff] [blame] | 161 | DBus::Error& error) { // NOLINT |
| 162 | return DoEnumerateDevices(true); |
| 163 | } |
| 164 | |
Ben Chan | 190d3cf | 2011-07-07 09:38:48 -0700 | [diff] [blame] | 165 | DBusDisk CrosDisksServer::GetDeviceProperties(const string& device_path, |
Ben Chan | 8dcede8 | 2011-07-25 20:56:13 -0700 | [diff] [blame] | 166 | DBus::Error& error) { // NOLINT |
Ben Chan | f51ff00 | 2011-04-25 12:41:57 -0700 | [diff] [blame] | 167 | Disk disk; |
| 168 | if (!disk_manager_->GetDiskByDevicePath(device_path, &disk)) { |
Ben Chan | 190d3cf | 2011-07-07 09:38:48 -0700 | [diff] [blame] | 169 | string message = "Could not get the properties of device " + device_path; |
Ben Chan | f51ff00 | 2011-04-25 12:41:57 -0700 | [diff] [blame] | 170 | LOG(ERROR) << message; |
Ben Chan | 6d0b272 | 2011-11-18 08:24:14 -0800 | [diff] [blame] | 171 | error.set(kCrosDisksServiceError, message.c_str()); |
Ben Chan | f51ff00 | 2011-04-25 12:41:57 -0700 | [diff] [blame] | 172 | } |
| 173 | return disk.ToDBusFormat(); |
| 174 | } |
| 175 | |
Ben Chan | c1e766c | 2011-11-21 12:56:59 -0800 | [diff] [blame] | 176 | void 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 Chan | 5988f29 | 2012-09-18 08:32:42 -0700 | [diff] [blame] | 189 | void CrosDisksServer::OnScreenIsLocked() { |
| 190 | // no-op |
| 191 | } |
| 192 | |
| 193 | void CrosDisksServer::OnScreenIsUnlocked() { |
| 194 | // no-op |
| 195 | } |
| 196 | |
Ben Chan | b3bf8d1 | 2013-04-23 13:57:55 -0700 | [diff] [blame^] | 197 | void CrosDisksServer::OnSessionStarted() { |
Ben Chan | 8dcede8 | 2011-07-25 20:56:13 -0700 | [diff] [blame] | 198 | for (vector<MountManager*>::iterator manager_iter = mount_managers_.begin(); |
| 199 | manager_iter != mount_managers_.end(); ++manager_iter) { |
| 200 | MountManager* manager = *manager_iter; |
Ben Chan | b3bf8d1 | 2013-04-23 13:57:55 -0700 | [diff] [blame^] | 201 | manager->StartSession(); |
Ben Chan | 8dcede8 | 2011-07-25 20:56:13 -0700 | [diff] [blame] | 202 | } |
Ben Chan | 6e72692 | 2011-06-28 15:54:32 -0700 | [diff] [blame] | 203 | } |
| 204 | |
Ben Chan | b3bf8d1 | 2013-04-23 13:57:55 -0700 | [diff] [blame^] | 205 | void CrosDisksServer::OnSessionStopped() { |
Ben Chan | 8dcede8 | 2011-07-25 20:56:13 -0700 | [diff] [blame] | 206 | for (vector<MountManager*>::iterator manager_iter = mount_managers_.begin(); |
| 207 | manager_iter != mount_managers_.end(); ++manager_iter) { |
| 208 | MountManager* manager = *manager_iter; |
Ben Chan | b3bf8d1 | 2013-04-23 13:57:55 -0700 | [diff] [blame^] | 209 | manager->StopSession(); |
Ben Chan | 8dcede8 | 2011-07-25 20:56:13 -0700 | [diff] [blame] | 210 | } |
Ben Chan | 6e72692 | 2011-06-28 15:54:32 -0700 | [diff] [blame] | 211 | } |
| 212 | |
| 213 | void 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 Chan | 6e72692 | 2011-06-28 15:54:32 -0700 | [diff] [blame] | 227 | 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 Chan | b092d75 | 2011-07-13 11:44:38 -0700 | [diff] [blame] | 238 | void CrosDisksServer::InitializeProperties() { |
| 239 | try { |
| 240 | DBus::Variant value; |
Ben Chan | 8dcede8 | 2011-07-25 20:56:13 -0700 | [diff] [blame] | 241 | value.writer().append_bool(platform_->experimental_features_enabled()); |
Ben Chan | 6d0b272 | 2011-11-18 08:24:14 -0800 | [diff] [blame] | 242 | CrosDisks_adaptor::set_property(kExperimentalFeaturesEnabled, value); |
Ben Chan | 8dcede8 | 2011-07-25 20:56:13 -0700 | [diff] [blame] | 243 | } catch (const DBus::Error& e) { // NOLINT |
Ben Chan | b092d75 | 2011-07-13 11:44:38 -0700 | [diff] [blame] | 244 | LOG(FATAL) << "Failed to initialize properties: " << e.what(); |
| 245 | } |
| 246 | } |
| 247 | |
| 248 | void CrosDisksServer::on_set_property( |
| 249 | DBus::InterfaceAdaptor& interface, // NOLINT |
Ben Chan | 8dcede8 | 2011-07-25 20:56:13 -0700 | [diff] [blame] | 250 | const string& property, const DBus::Variant& value) { |
Ben Chan | 6d0b272 | 2011-11-18 08:24:14 -0800 | [diff] [blame] | 251 | if (property == kExperimentalFeaturesEnabled) { |
Ben Chan | 8dcede8 | 2011-07-25 20:56:13 -0700 | [diff] [blame] | 252 | platform_->set_experimental_features_enabled(value.reader().get_bool()); |
Ben Chan | b092d75 | 2011-07-13 11:44:38 -0700 | [diff] [blame] | 253 | } |
| 254 | } |
| 255 | |
Ben Chan | bdc3974 | 2011-05-11 17:51:26 -0700 | [diff] [blame] | 256 | } // namespace cros_disks |