blob: ce08871019844e2eb3ec8e05f3c0d4e38ca8d277 [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 Chan5ccd9fe2013-11-13 18:28:27 -08005#include "cros-disks/cros_disks_server.h"
Ben Chan6e726922011-06-28 15:54:32 -07006
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 Chan5ccd9fe2013-11-13 18:28:27 -080010#include "cros-disks/archive_manager.h"
11#include "cros-disks/device_event.h"
Ben Chanbdc39742011-05-11 17:51:26 -070012#include "cros-disks/disk.h"
Ben Chan5ccd9fe2013-11-13 18:28:27 -080013#include "cros-disks/disk_manager.h"
14#include "cros-disks/format_manager.h"
Ben Chan8dcede82011-07-25 20:56:13 -070015#include "cros-disks/platform.h"
Klemen Kozjekb0658852017-08-15 13:03:48 +090016#include "cros-disks/rename_manager.h"
Szymon Sidor2733b512011-06-30 18:00:51 -070017
Ben Chan190d3cf2011-07-07 09:38:48 -070018using std::string;
19using std::vector;
Ryan Cairnsea6505f2011-04-10 19:54:53 -070020
Ben Chan460439f2011-09-13 09:16:28 -070021namespace cros_disks {
Ryan Cairnsea6505f2011-04-10 19:54:53 -070022
Ben Chan6e726922011-06-28 15:54:32 -070023CrosDisksServer::CrosDisksServer(DBus::Connection& connection, // NOLINT
Ben Chan8dcede82011-07-25 20:56:13 -070024 Platform* platform,
Ben Chan8dcede82011-07-25 20:56:13 -070025 DiskManager* disk_manager,
Klemen Kozjekb0658852017-08-15 13:03:48 +090026 FormatManager* format_manager,
27 RenameManager* rename_manager)
Ben Chan6d0b2722011-11-18 08:24:14 -080028 : DBus::ObjectAdaptor(connection, kCrosDisksServicePath),
Ben Chan8dcede82011-07-25 20:56:13 -070029 platform_(platform),
Ben Chan6e726922011-06-28 15:54:32 -070030 disk_manager_(disk_manager),
Klemen Kozjekb0658852017-08-15 13:03:48 +090031 format_manager_(format_manager),
32 rename_manager_(rename_manager) {
Ben Chan8dcede82011-07-25 20:56:13 -070033 CHECK(platform_) << "Invalid platform object";
Ben Chanb092d752011-07-13 11:44:38 -070034 CHECK(disk_manager_) << "Invalid disk manager object";
35 CHECK(format_manager_) << "Invalid format manager object";
Klemen Kozjekb0658852017-08-15 13:03:48 +090036 CHECK(rename_manager_) << "Invalid rename manager object";
Szymon Sidor2733b512011-06-30 18:00:51 -070037
Ben Chanc1e766c2011-11-21 12:56:59 -080038 format_manager_->set_observer(this);
Klemen Kozjekb0658852017-08-15 13:03:48 +090039 rename_manager_->set_observer(this);
Ben Chanf51ff002011-04-25 12:41:57 -070040}
Ryan Cairnsea6505f2011-04-10 19:54:53 -070041
Ben Chanf47fc352013-05-03 11:28:57 -070042void CrosDisksServer::RegisterMountManager(MountManager* mount_manager) {
43 CHECK(mount_manager) << "Invalid mount manager object";
44 mount_managers_.push_back(mount_manager);
45}
46
Ryan Cairnsea6505f2011-04-10 19:54:53 -070047bool CrosDisksServer::IsAlive(DBus::Error& error) { // NOLINT
48 return true;
49}
50
Ben Chanc1e766c2011-11-21 12:56:59 -080051void CrosDisksServer::Format(const string& path,
52 const string& filesystem_type,
53 const vector<string>& options,
Ben Chande0e3f62017-09-26 06:28:39 -070054 DBus::Error& error) { // NOLINT
Ben Chanc833a522012-09-27 23:47:00 -070055 FormatErrorType error_type = FORMAT_ERROR_NONE;
56 Disk disk;
57 if (!disk_manager_->GetDiskByDevicePath(path, &disk)) {
58 error_type = FORMAT_ERROR_INVALID_DEVICE_PATH;
59 } else if (disk.is_on_boot_device()) {
60 error_type = FORMAT_ERROR_DEVICE_NOT_ALLOWED;
61 } else {
Ben Chande0e3f62017-09-26 06:28:39 -070062 error_type = format_manager_->StartFormatting(path, disk.device_file(),
63 filesystem_type);
Ben Chanc833a522012-09-27 23:47:00 -070064 }
65
Ben Chanc1e766c2011-11-21 12:56:59 -080066 if (error_type != FORMAT_ERROR_NONE) {
Ben Chande0e3f62017-09-26 06:28:39 -070067 LOG(ERROR) << "Could not format device '" << path << "' as filesystem '"
68 << filesystem_type << "'";
Ben Chanc1e766c2011-11-21 12:56:59 -080069 FormatCompleted(error_type, path);
Szymon Sidor2733b512011-06-30 18:00:51 -070070 }
Szymon Sidor2733b512011-06-30 18:00:51 -070071}
72
Klemen Kozjekb0658852017-08-15 13:03:48 +090073void CrosDisksServer::Rename(const string& path,
74 const string& volume_name,
75 DBus::Error& error) { // NOLINT
76 RenameErrorType error_type = RENAME_ERROR_NONE;
77 Disk disk;
78 if (!disk_manager_->GetDiskByDevicePath(path, &disk)) {
79 error_type = RENAME_ERROR_INVALID_DEVICE_PATH;
80 } else if (disk.is_on_boot_device() || disk.is_read_only()) {
81 error_type = RENAME_ERROR_DEVICE_NOT_ALLOWED;
82 } else {
Ben Chande0e3f62017-09-26 06:28:39 -070083 error_type = rename_manager_->StartRenaming(
84 path, disk.device_file(), volume_name, disk.filesystem_type());
Klemen Kozjekb0658852017-08-15 13:03:48 +090085 }
86
87 if (error_type != RENAME_ERROR_NONE) {
Ben Chande0e3f62017-09-26 06:28:39 -070088 LOG(ERROR) << "Could not rename device '" << path << "' as '" << volume_name
89 << "'";
Klemen Kozjekb0658852017-08-15 13:03:48 +090090 RenameCompleted(error_type, path);
91 }
92}
93
Tatsuhisa Yamaguchib670bd12016-09-28 23:06:44 +090094MountManager* CrosDisksServer::FindMounter(const string& source_path) const {
95 for (const auto& manager : mount_managers_) {
96 if (manager->CanMount(source_path)) {
97 return manager;
98 }
99 }
100 return nullptr;
101}
102
Ben Chand3fdc722011-07-21 18:15:22 -0700103void CrosDisksServer::Mount(const string& path,
Ben Chan8dcede82011-07-25 20:56:13 -0700104 const string& filesystem_type,
105 const vector<string>& options,
106 DBus::Error& error) { // NOLINT
Ben Chanfcb2fc02011-11-21 09:44:07 -0800107 MountErrorType error_type = MOUNT_ERROR_INVALID_PATH;
Ben Chan6d0b2722011-11-18 08:24:14 -0800108 MountSourceType source_type = MOUNT_SOURCE_INVALID;
Ben Chanadc5d002014-03-12 15:02:26 -0700109 string source_path;
Ben Chand3fdc722011-07-21 18:15:22 -0700110 string mount_path;
Ben Chan8dcede82011-07-25 20:56:13 -0700111
Ben Chanadc5d002014-03-12 15:02:26 -0700112 if (platform_->GetRealPath(path, &source_path)) {
Tatsuhisa Yamaguchib670bd12016-09-28 23:06:44 +0900113 MountManager* mounter = FindMounter(source_path);
114 if (mounter) {
115 source_type = mounter->GetMountSourceType();
116 error_type =
117 mounter->Mount(source_path, filesystem_type, options, &mount_path);
Ben Chan8dcede82011-07-25 20:56:13 -0700118 }
119 }
120
Ben Chanfcb2fc02011-11-21 09:44:07 -0800121 if (error_type != MOUNT_ERROR_NONE) {
Ben Chan8dcede82011-07-25 20:56:13 -0700122 LOG(ERROR) << "Failed to mount '" << path << "'";
Ben Chand3fdc722011-07-21 18:15:22 -0700123 }
Ben Chan8dcede82011-07-25 20:56:13 -0700124 MountCompleted(error_type, path, source_type, mount_path);
Ben Chand3fdc722011-07-21 18:15:22 -0700125}
126
127void CrosDisksServer::Unmount(const string& path,
Ben Chan8dcede82011-07-25 20:56:13 -0700128 const vector<string>& options,
129 DBus::Error& error) { // NOLINT
Ben Chanfcb2fc02011-11-21 09:44:07 -0800130 MountErrorType error_type = MOUNT_ERROR_INVALID_PATH;
Ben Chan63ec9c42014-04-21 19:13:23 -0700131 for (const auto& manager : mount_managers_) {
Ben Chan8dcede82011-07-25 20:56:13 -0700132 if (manager->CanUnmount(path)) {
133 error_type = manager->Unmount(path, options);
134 break;
135 }
136 }
137
Ben Chanfcb2fc02011-11-21 09:44:07 -0800138 if (error_type != MOUNT_ERROR_NONE) {
Ben Chan8dcede82011-07-25 20:56:13 -0700139 string message = "Failed to unmount '" + path + "'";
Ben Chan6d0b2722011-11-18 08:24:14 -0800140 error.set(kCrosDisksServiceError, message.c_str());
Ben Chand3fdc722011-07-21 18:15:22 -0700141 }
142}
143
Ben Chan8f513762011-11-14 12:44:42 -0800144void CrosDisksServer::UnmountAll(DBus::Error& error) { // NOLINT
145 DoUnmountAll();
146}
147
148void CrosDisksServer::DoUnmountAll() {
Ben Chan63ec9c42014-04-21 19:13:23 -0700149 for (const auto& manager : mount_managers_) {
Ben Chan8f513762011-11-14 12:44:42 -0800150 manager->UnmountAll();
151 }
152}
153
Ben Chan190d3cf2011-07-07 09:38:48 -0700154vector<string> CrosDisksServer::DoEnumerateDevices(
Ben Chan490319f2011-05-06 14:00:42 -0700155 bool auto_mountable_only) const {
Ben Chan190d3cf2011-07-07 09:38:48 -0700156 vector<Disk> disks = disk_manager_->EnumerateDisks();
157 vector<string> devices;
Ben Chanf51ff002011-04-25 12:41:57 -0700158 devices.reserve(disks.size());
Ben Chan63ec9c42014-04-21 19:13:23 -0700159 for (const auto& disk : disks) {
160 if (!auto_mountable_only || disk.is_auto_mountable()) {
161 devices.push_back(disk.native_path());
Ben Chan490319f2011-05-06 14:00:42 -0700162 }
163 }
Ben Chanf51ff002011-04-25 12:41:57 -0700164 return devices;
165}
166
Ben Chan190d3cf2011-07-07 09:38:48 -0700167vector<string> CrosDisksServer::EnumerateDevices(
Ben Chan490319f2011-05-06 14:00:42 -0700168 DBus::Error& error) { // NOLINT
169 return DoEnumerateDevices(false);
170}
171
Ben Chan190d3cf2011-07-07 09:38:48 -0700172vector<string> CrosDisksServer::EnumerateAutoMountableDevices(
Ben Chan490319f2011-05-06 14:00:42 -0700173 DBus::Error& error) { // NOLINT
174 return DoEnumerateDevices(true);
175}
176
Ben Chan0214e302017-10-17 15:39:16 -0700177vector<CrosDisksServer::DBusMountEntry> CrosDisksServer::EnumerateMountEntries(
Ben Chan8fb742b2014-04-28 23:46:57 -0700178 DBus::Error& error) { // NOLINT
Ben Chan0214e302017-10-17 15:39:16 -0700179 vector<DBusMountEntry> dbus_mount_entries;
Ben Chan8fb742b2014-04-28 23:46:57 -0700180 for (const auto& manager : mount_managers_) {
181 vector<MountEntry> mount_entries;
182 manager->GetMountEntries(&mount_entries);
183 for (const auto& mount_entry : mount_entries) {
Ben Chan0214e302017-10-17 15:39:16 -0700184 dbus_mount_entries.push_back(
185 {mount_entry.error_type, mount_entry.source_path,
186 mount_entry.source_type, mount_entry.mount_path});
Ben Chan8fb742b2014-04-28 23:46:57 -0700187 }
188 }
189 return dbus_mount_entries;
190}
191
Ben Chan190d3cf2011-07-07 09:38:48 -0700192DBusDisk CrosDisksServer::GetDeviceProperties(const string& device_path,
Ben Chan8dcede82011-07-25 20:56:13 -0700193 DBus::Error& error) { // NOLINT
Ben Chanf51ff002011-04-25 12:41:57 -0700194 Disk disk;
195 if (!disk_manager_->GetDiskByDevicePath(device_path, &disk)) {
Ben Chan190d3cf2011-07-07 09:38:48 -0700196 string message = "Could not get the properties of device " + device_path;
Ben Chanf51ff002011-04-25 12:41:57 -0700197 LOG(ERROR) << message;
Ben Chan6d0b2722011-11-18 08:24:14 -0800198 error.set(kCrosDisksServiceError, message.c_str());
Ben Chanf51ff002011-04-25 12:41:57 -0700199 }
200 return disk.ToDBusFormat();
201}
202
Ben Chanc1e766c2011-11-21 12:56:59 -0800203void CrosDisksServer::OnFormatCompleted(const string& device_path,
204 FormatErrorType error_type) {
Ben Chanc1e766c2011-11-21 12:56:59 -0800205 FormatCompleted(error_type, device_path);
206}
207
Klemen Kozjekb0658852017-08-15 13:03:48 +0900208void CrosDisksServer::OnRenameCompleted(const string& device_path,
209 RenameErrorType error_type) {
210 RenameCompleted(error_type, device_path);
211}
212
Ben Chan5988f292012-09-18 08:32:42 -0700213void CrosDisksServer::OnScreenIsLocked() {
214 // no-op
215}
216
217void CrosDisksServer::OnScreenIsUnlocked() {
218 // no-op
219}
220
Ben Chanb3bf8d12013-04-23 13:57:55 -0700221void CrosDisksServer::OnSessionStarted() {
Ben Chan63ec9c42014-04-21 19:13:23 -0700222 for (const auto& manager : mount_managers_) {
Ben Chanb3bf8d12013-04-23 13:57:55 -0700223 manager->StartSession();
Ben Chan8dcede82011-07-25 20:56:13 -0700224 }
Ben Chan6e726922011-06-28 15:54:32 -0700225}
226
Ben Chanb3bf8d12013-04-23 13:57:55 -0700227void CrosDisksServer::OnSessionStopped() {
Ben Chan63ec9c42014-04-21 19:13:23 -0700228 for (const auto& manager : mount_managers_) {
Ben Chanb3bf8d12013-04-23 13:57:55 -0700229 manager->StopSession();
Ben Chan8dcede82011-07-25 20:56:13 -0700230 }
Ben Chan6e726922011-06-28 15:54:32 -0700231}
232
233void CrosDisksServer::DispatchDeviceEvent(const DeviceEvent& event) {
234 switch (event.event_type) {
235 case DeviceEvent::kDeviceAdded:
236 DeviceAdded(event.device_path);
237 break;
238 case DeviceEvent::kDeviceScanned:
239 DeviceScanned(event.device_path);
240 break;
241 case DeviceEvent::kDeviceRemoved:
242 DeviceRemoved(event.device_path);
243 break;
244 case DeviceEvent::kDiskAdded:
245 DiskAdded(event.device_path);
246 break;
Ben Chan6e726922011-06-28 15:54:32 -0700247 case DeviceEvent::kDiskChanged:
248 DiskChanged(event.device_path);
249 break;
250 case DeviceEvent::kDiskRemoved:
251 DiskRemoved(event.device_path);
252 break;
253 default:
254 break;
255 }
256}
257
Ben Chanbdc39742011-05-11 17:51:26 -0700258} // namespace cros_disks