blob: f541e40bfe57aa206bda2be13c3a7f09c72f46c2 [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,
Ben Chan8dcede82011-07-25 20:56:13 -070024 DiskManager* disk_manager,
25 FormatManager* format_manager)
Ben Chan6d0b2722011-11-18 08:24:14 -080026 : DBus::ObjectAdaptor(connection, kCrosDisksServicePath),
Ben Chan8dcede82011-07-25 20:56:13 -070027 platform_(platform),
Ben Chan6e726922011-06-28 15:54:32 -070028 disk_manager_(disk_manager),
Ben Chan89cf29e2011-08-10 13:11:05 -070029 format_manager_(format_manager) {
Ben Chan8dcede82011-07-25 20:56:13 -070030 CHECK(platform_) << "Invalid platform object";
Ben Chanb092d752011-07-13 11:44:38 -070031 CHECK(disk_manager_) << "Invalid disk manager object";
32 CHECK(format_manager_) << "Invalid format manager object";
Szymon Sidor2733b512011-06-30 18:00:51 -070033
Ben Chanb092d752011-07-13 11:44:38 -070034 InitializeProperties();
Ben Chanc1e766c2011-11-21 12:56:59 -080035 format_manager_->set_observer(this);
Ben Chanf51ff002011-04-25 12:41:57 -070036}
Ryan Cairnsea6505f2011-04-10 19:54:53 -070037
Ben Chan190d3cf2011-07-07 09:38:48 -070038CrosDisksServer::~CrosDisksServer() {
39}
Ryan Cairnsea6505f2011-04-10 19:54:53 -070040
Ben Chanf47fc352013-05-03 11:28:57 -070041void CrosDisksServer::RegisterMountManager(MountManager* mount_manager) {
42 CHECK(mount_manager) << "Invalid mount manager object";
43 mount_managers_.push_back(mount_manager);
44}
45
Ryan Cairnsea6505f2011-04-10 19:54:53 -070046bool CrosDisksServer::IsAlive(DBus::Error& error) { // NOLINT
47 return true;
48}
49
Ben Chanc1e766c2011-11-21 12:56:59 -080050void CrosDisksServer::Format(const string& path,
51 const string& filesystem_type,
52 const vector<string>& options,
53 DBus::Error &error) { // NOLINT
54 FormatDevice(path, filesystem_type, error);
Szymon Sidor2733b512011-06-30 18:00:51 -070055}
56
Ben Chanc1e766c2011-11-21 12:56:59 -080057// TODO(benchan): Remove this method after Chrome switches to use Format().
58bool CrosDisksServer::FormatDevice(const string& path,
59 const string& filesystem_type,
Ben Chan8dcede82011-07-25 20:56:13 -070060 DBus::Error &error) { // NOLINT
Ben Chanc833a522012-09-27 23:47:00 -070061 FormatErrorType error_type = FORMAT_ERROR_NONE;
62 Disk disk;
63 if (!disk_manager_->GetDiskByDevicePath(path, &disk)) {
64 error_type = FORMAT_ERROR_INVALID_DEVICE_PATH;
65 } else if (disk.is_on_boot_device()) {
66 error_type = FORMAT_ERROR_DEVICE_NOT_ALLOWED;
67 } else {
Toni Barzic031dc712012-11-20 18:15:46 -080068 error_type =
69 format_manager_->StartFormatting(disk.device_file(), filesystem_type);
Ben Chanc833a522012-09-27 23:47:00 -070070 }
71
Ben Chanc1e766c2011-11-21 12:56:59 -080072 if (error_type != FORMAT_ERROR_NONE) {
73 LOG(ERROR) << "Could not format device '" << path
74 << "' as filesystem '" << filesystem_type << "'";
75 FormatCompleted(error_type, path);
Szymon Sidor2733b512011-06-30 18:00:51 -070076 return false;
77 }
78 return true;
79}
80
Ben Chand3fdc722011-07-21 18:15:22 -070081void CrosDisksServer::Mount(const string& path,
Ben Chan8dcede82011-07-25 20:56:13 -070082 const string& filesystem_type,
83 const vector<string>& options,
84 DBus::Error& error) { // NOLINT
Ben Chanfcb2fc02011-11-21 09:44:07 -080085 MountErrorType error_type = MOUNT_ERROR_INVALID_PATH;
Ben Chan6d0b2722011-11-18 08:24:14 -080086 MountSourceType source_type = MOUNT_SOURCE_INVALID;
Ben Chand3fdc722011-07-21 18:15:22 -070087 string mount_path;
Ben Chan8dcede82011-07-25 20:56:13 -070088
89 for (vector<MountManager*>::iterator manager_iter = mount_managers_.begin();
90 manager_iter != mount_managers_.end(); ++manager_iter) {
91 MountManager* manager = *manager_iter;
92 if (manager->CanMount(path)) {
93 source_type = manager->GetMountSourceType();
94 error_type = manager->Mount(path, filesystem_type, options, &mount_path);
95 break;
96 }
97 }
98
Ben Chanfcb2fc02011-11-21 09:44:07 -080099 if (error_type != MOUNT_ERROR_NONE) {
Ben Chan8dcede82011-07-25 20:56:13 -0700100 LOG(ERROR) << "Failed to mount '" << path << "'";
Ben Chand3fdc722011-07-21 18:15:22 -0700101 }
Ben Chan8dcede82011-07-25 20:56:13 -0700102 MountCompleted(error_type, path, source_type, mount_path);
Ben Chand3fdc722011-07-21 18:15:22 -0700103}
104
105void CrosDisksServer::Unmount(const string& path,
Ben Chan8dcede82011-07-25 20:56:13 -0700106 const vector<string>& options,
107 DBus::Error& error) { // NOLINT
Ben Chanfcb2fc02011-11-21 09:44:07 -0800108 MountErrorType error_type = MOUNT_ERROR_INVALID_PATH;
Ben Chan8dcede82011-07-25 20:56:13 -0700109 for (vector<MountManager*>::iterator manager_iter = mount_managers_.begin();
110 manager_iter != mount_managers_.end(); ++manager_iter) {
111 MountManager* manager = *manager_iter;
112 if (manager->CanUnmount(path)) {
113 error_type = manager->Unmount(path, options);
114 break;
115 }
116 }
117
Ben Chanfcb2fc02011-11-21 09:44:07 -0800118 if (error_type != MOUNT_ERROR_NONE) {
Ben Chan8dcede82011-07-25 20:56:13 -0700119 string message = "Failed to unmount '" + path + "'";
Ben Chan6d0b2722011-11-18 08:24:14 -0800120 error.set(kCrosDisksServiceError, message.c_str());
Ben Chand3fdc722011-07-21 18:15:22 -0700121 }
122}
123
Ben Chan8f513762011-11-14 12:44:42 -0800124void CrosDisksServer::UnmountAll(DBus::Error& error) { // NOLINT
125 DoUnmountAll();
126}
127
128void CrosDisksServer::DoUnmountAll() {
129 for (vector<MountManager*>::iterator manager_iter = mount_managers_.begin();
130 manager_iter != mount_managers_.end(); ++manager_iter) {
131 MountManager* manager = *manager_iter;
132 manager->UnmountAll();
133 }
134}
135
Ben Chan190d3cf2011-07-07 09:38:48 -0700136vector<string> CrosDisksServer::DoEnumerateDevices(
Ben Chan490319f2011-05-06 14:00:42 -0700137 bool auto_mountable_only) const {
Ben Chan190d3cf2011-07-07 09:38:48 -0700138 vector<Disk> disks = disk_manager_->EnumerateDisks();
139 vector<string> devices;
Ben Chanf51ff002011-04-25 12:41:57 -0700140 devices.reserve(disks.size());
Ben Chan8dcede82011-07-25 20:56:13 -0700141 for (vector<Disk>::const_iterator disk_iterator = disks.begin();
142 disk_iterator != disks.end(); ++disk_iterator) {
Ben Chan1c2d4252011-06-03 13:33:49 -0700143 if (!auto_mountable_only || disk_iterator->is_auto_mountable()) {
Ben Chan490319f2011-05-06 14:00:42 -0700144 devices.push_back(disk_iterator->native_path());
145 }
146 }
Ben Chanf51ff002011-04-25 12:41:57 -0700147 return devices;
148}
149
Ben Chan190d3cf2011-07-07 09:38:48 -0700150vector<string> CrosDisksServer::EnumerateDevices(
Ben Chan490319f2011-05-06 14:00:42 -0700151 DBus::Error& error) { // NOLINT
152 return DoEnumerateDevices(false);
153}
154
Ben Chan190d3cf2011-07-07 09:38:48 -0700155vector<string> CrosDisksServer::EnumerateAutoMountableDevices(
Ben Chan490319f2011-05-06 14:00:42 -0700156 DBus::Error& error) { // NOLINT
157 return DoEnumerateDevices(true);
158}
159
Ben Chan190d3cf2011-07-07 09:38:48 -0700160DBusDisk CrosDisksServer::GetDeviceProperties(const string& device_path,
Ben Chan8dcede82011-07-25 20:56:13 -0700161 DBus::Error& error) { // NOLINT
Ben Chanf51ff002011-04-25 12:41:57 -0700162 Disk disk;
163 if (!disk_manager_->GetDiskByDevicePath(device_path, &disk)) {
Ben Chan190d3cf2011-07-07 09:38:48 -0700164 string message = "Could not get the properties of device " + device_path;
Ben Chanf51ff002011-04-25 12:41:57 -0700165 LOG(ERROR) << message;
Ben Chan6d0b2722011-11-18 08:24:14 -0800166 error.set(kCrosDisksServiceError, message.c_str());
Ben Chanf51ff002011-04-25 12:41:57 -0700167 }
168 return disk.ToDBusFormat();
169}
170
Ben Chanc1e766c2011-11-21 12:56:59 -0800171void CrosDisksServer::OnFormatCompleted(const string& device_path,
172 FormatErrorType error_type) {
173 // TODO(benchan): Deprecate the FormattingFinished signal once Chrome
174 // switches to observe the FormatCompleted signal instead.
175 if (error_type != FORMAT_ERROR_NONE) {
176 FormattingFinished("!" + device_path);
177 LOG(ERROR) << "Failed to format '" << device_path << "'";
178 } else {
179 FormattingFinished(device_path);
180 }
181 FormatCompleted(error_type, device_path);
182}
183
Ben Chan5988f292012-09-18 08:32:42 -0700184void CrosDisksServer::OnScreenIsLocked() {
185 // no-op
186}
187
188void CrosDisksServer::OnScreenIsUnlocked() {
189 // no-op
190}
191
Ben Chanb3bf8d12013-04-23 13:57:55 -0700192void CrosDisksServer::OnSessionStarted() {
Ben Chan8dcede82011-07-25 20:56:13 -0700193 for (vector<MountManager*>::iterator manager_iter = mount_managers_.begin();
194 manager_iter != mount_managers_.end(); ++manager_iter) {
195 MountManager* manager = *manager_iter;
Ben Chanb3bf8d12013-04-23 13:57:55 -0700196 manager->StartSession();
Ben Chan8dcede82011-07-25 20:56:13 -0700197 }
Ben Chan6e726922011-06-28 15:54:32 -0700198}
199
Ben Chanb3bf8d12013-04-23 13:57:55 -0700200void CrosDisksServer::OnSessionStopped() {
Ben Chan8dcede82011-07-25 20:56:13 -0700201 for (vector<MountManager*>::iterator manager_iter = mount_managers_.begin();
202 manager_iter != mount_managers_.end(); ++manager_iter) {
203 MountManager* manager = *manager_iter;
Ben Chanb3bf8d12013-04-23 13:57:55 -0700204 manager->StopSession();
Ben Chan8dcede82011-07-25 20:56:13 -0700205 }
Ben Chan6e726922011-06-28 15:54:32 -0700206}
207
208void CrosDisksServer::DispatchDeviceEvent(const DeviceEvent& event) {
209 switch (event.event_type) {
210 case DeviceEvent::kDeviceAdded:
211 DeviceAdded(event.device_path);
212 break;
213 case DeviceEvent::kDeviceScanned:
214 DeviceScanned(event.device_path);
215 break;
216 case DeviceEvent::kDeviceRemoved:
217 DeviceRemoved(event.device_path);
218 break;
219 case DeviceEvent::kDiskAdded:
220 DiskAdded(event.device_path);
221 break;
Ben Chan6e726922011-06-28 15:54:32 -0700222 case DeviceEvent::kDiskChanged:
223 DiskChanged(event.device_path);
224 break;
225 case DeviceEvent::kDiskRemoved:
226 DiskRemoved(event.device_path);
227 break;
228 default:
229 break;
230 }
231}
232
Ben Chanb092d752011-07-13 11:44:38 -0700233void CrosDisksServer::InitializeProperties() {
234 try {
235 DBus::Variant value;
Ben Chan8dcede82011-07-25 20:56:13 -0700236 value.writer().append_bool(platform_->experimental_features_enabled());
Ben Chan6d0b2722011-11-18 08:24:14 -0800237 CrosDisks_adaptor::set_property(kExperimentalFeaturesEnabled, value);
Ben Chan8dcede82011-07-25 20:56:13 -0700238 } catch (const DBus::Error& e) { // NOLINT
Ben Chanb092d752011-07-13 11:44:38 -0700239 LOG(FATAL) << "Failed to initialize properties: " << e.what();
240 }
241}
242
243void CrosDisksServer::on_set_property(
244 DBus::InterfaceAdaptor& interface, // NOLINT
Ben Chan8dcede82011-07-25 20:56:13 -0700245 const string& property, const DBus::Variant& value) {
Ben Chan6d0b2722011-11-18 08:24:14 -0800246 if (property == kExperimentalFeaturesEnabled) {
Ben Chan8dcede82011-07-25 20:56:13 -0700247 platform_->set_experimental_features_enabled(value.reader().get_bool());
Ben Chanb092d752011-07-13 11:44:38 -0700248 }
249}
250
Ben Chanbdc39742011-05-11 17:51:26 -0700251} // namespace cros_disks