Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(87)

Side by Side Diff: chrome/browser/chromeos/cros/mount_library.cc

Issue 8499009: Remove unused MountLibrary (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebased on ToT Created 9 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « chrome/browser/chromeos/cros/mount_library.h ('k') | chrome/chrome_browser.gypi » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2011 The Chromium 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
5 #include "chrome/browser/chromeos/cros/mount_library.h"
6
7 #include <set>
8 #include <sys/statvfs.h>
9 #include <vector>
10
11 #include "base/message_loop.h"
12 #include "base/string_util.h"
13 #include "chrome/browser/chromeos/cros/cros_library.h"
14 #include "content/public/browser/browser_thread.h"
15
16 using content::BrowserThread;
17
18 const char* kLibraryNotLoaded = "Cros Library not loaded";
19 const char* kDeviceNotFound = "Device could not be found";
20
21 namespace chromeos {
22
23 // static
24 std::string MountLibrary::MountTypeToString(MountType type) {
25 switch (type) {
26 case MOUNT_TYPE_DEVICE:
27 return "device";
28 case MOUNT_TYPE_ARCHIVE:
29 return "file";
30 case MOUNT_TYPE_NETWORK_STORAGE:
31 return "network";
32 case MOUNT_TYPE_INVALID:
33 return "invalid";
34 default:
35 NOTREACHED();
36 }
37 return "";
38 }
39
40 std::string MountLibrary::MountConditionToString(MountCondition condition) {
41 switch (condition) {
42 case MOUNT_CONDITION_NONE:
43 return "";
44 case MOUNT_CONDITION_UNKNOWN_FILESYSTEM:
45 return "unknown_filesystem";
46 case MOUNT_CONDITION_UNSUPPORTED_FILESYSTEM:
47 return "unsupported_filesystem";
48 default:
49 NOTREACHED();
50 }
51 return "";
52 }
53
54 // static
55 MountType MountLibrary::MountTypeFromString(
56 const std::string& type_str) {
57 if (type_str == "device") {
58 return MOUNT_TYPE_DEVICE;
59 } else if (type_str == "network") {
60 return MOUNT_TYPE_NETWORK_STORAGE;
61 } else if (type_str == "file") {
62 return MOUNT_TYPE_ARCHIVE;
63 } else {
64 return MOUNT_TYPE_INVALID;
65 }
66 }
67
68 MountLibrary::Disk::Disk(const std::string& device_path,
69 const std::string& mount_path,
70 const std::string& system_path,
71 const std::string& file_path,
72 const std::string& device_label,
73 const std::string& drive_label,
74 const std::string& parent_path,
75 const std::string& system_path_prefix,
76 DeviceType device_type,
77 uint64 total_size,
78 bool is_parent,
79 bool is_read_only,
80 bool has_media,
81 bool on_boot_device,
82 bool is_hidden)
83 : device_path_(device_path),
84 mount_path_(mount_path),
85 system_path_(system_path),
86 file_path_(file_path),
87 device_label_(device_label),
88 drive_label_(drive_label),
89 parent_path_(parent_path),
90 system_path_prefix_(system_path_prefix),
91 device_type_(device_type),
92 total_size_(total_size),
93 is_parent_(is_parent),
94 is_read_only_(is_read_only),
95 has_media_(has_media),
96 on_boot_device_(on_boot_device),
97 is_hidden_(is_hidden) {
98 }
99
100 MountLibrary::Disk::~Disk() {}
101
102 class MountLibcrosProxyImpl : public MountLibcrosProxy {
103 public:
104 virtual void CallMountPath(const char* source_path,
105 MountType type,
106 const MountPathOptions& options,
107 MountCompletedMonitor callback,
108 void* object) OVERRIDE {
109 chromeos::MountSourcePath(source_path, type, options, callback, object);
110 }
111
112 virtual void CallUnmountPath(const char* path,
113 UnmountRequestCallback callback,
114 void* object) OVERRIDE {
115 chromeos::UnmountMountPoint(path, callback, object);
116 }
117
118 virtual void CallRequestMountInfo(RequestMountInfoCallback callback,
119 void* object) OVERRIDE {
120 chromeos::RequestMountInfo(callback, object);
121 }
122
123 virtual void CallFormatDevice(const char* file_path,
124 const char* filesystem,
125 FormatRequestCallback callback,
126 void* object) OVERRIDE {
127 chromeos::FormatDevice(file_path, filesystem, callback, object);
128 }
129
130 virtual void CallGetDiskProperties(const char* device_path,
131 GetDiskPropertiesCallback callback,
132 void* object) OVERRIDE {
133 chromeos::GetDiskProperties(device_path, callback, object);
134 }
135
136 virtual MountEventConnection MonitorCrosDisks(
137 MountEventMonitor monitor,
138 MountCompletedMonitor mount_completed_monitor,
139 void* object) OVERRIDE {
140 return chromeos::MonitorAllMountEvents(
141 monitor, mount_completed_monitor, object);
142 }
143
144 virtual void DisconnectCrosDisksMonitorIfSet(
145 MountEventConnection conn) OVERRIDE {
146 if (conn)
147 chromeos::DisconnectMountEventMonitor(conn);
148 }
149 };
150
151 class MountLibraryImpl : public MountLibrary {
152
153 struct UnmountDeviceRecursiveCallbackData {
154 MountLibraryImpl* const object;
155 void* user_data;
156 UnmountDeviceRecursiveCallbackType callback;
157 size_t pending_callbacks_count;
158 bool success;
159
160 UnmountDeviceRecursiveCallbackData(MountLibraryImpl* const o, void* ud,
161 UnmountDeviceRecursiveCallbackType cb, int count)
162 : object(o),
163 user_data(ud),
164 callback(cb),
165 pending_callbacks_count(count),
166 success(true) {
167 }
168 };
169
170 public:
171 MountLibraryImpl() : libcros_proxy_(new MountLibcrosProxyImpl()),
172 mount_status_connection_(NULL) {
173 }
174
175 virtual ~MountLibraryImpl() {
176 libcros_proxy_->DisconnectCrosDisksMonitorIfSet(
177 mount_status_connection_);
178 }
179
180 // MountLibrary overrides.
181 virtual void Init() OVERRIDE {
182 DCHECK(CrosLibrary::Get()->libcros_loaded());
183 // Getting the monitor status so that the daemon starts up.
184 mount_status_connection_ = libcros_proxy_->MonitorCrosDisks(
185 &MonitorMountEventsHandler, &MountCompletedHandler, this);
186 }
187
188 virtual void AddObserver(Observer* observer) OVERRIDE {
189 observers_.AddObserver(observer);
190 }
191
192 virtual void RemoveObserver(Observer* observer) OVERRIDE {
193 observers_.RemoveObserver(observer);
194 }
195
196 virtual void MountPath(const char* source_path,
197 MountType type,
198 const MountPathOptions& options) OVERRIDE {
199 // Hidden and non-existent devices should not be mounted.
200 if (type == MOUNT_TYPE_DEVICE) {
201 DiskMap::const_iterator it = disks_.find(source_path);
202 if (it == disks_.end() || it->second->is_hidden()) {
203 MountCompletedHandler(this, MOUNT_ERROR_INTERNAL, source_path, type,
204 NULL);
205 return;
206 }
207 }
208 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
209 libcros_proxy_->CallMountPath(source_path, type, options,
210 &MountCompletedHandler, this);
211 }
212
213 virtual void UnmountPath(const char* mount_path) OVERRIDE {
214 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
215 libcros_proxy_->CallUnmountPath(mount_path, &UnmountMountPointCallback,
216 this);
217 }
218
219 virtual void GetSizeStatsOnFileThread(const char* mount_path,
220 size_t* total_size_kb, size_t* remaining_size_kb) OVERRIDE {
221 CHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
222
223 uint64_t total_size_uint64 = 0;
224 uint64_t remaining_size_uint64 = 0;
225
226 struct statvfs stat;
227 if (statvfs(mount_path, &stat) == 0) {
228 total_size_uint64 =
229 static_cast<uint64_t>(stat.f_blocks) * stat.f_frsize;
230 remaining_size_uint64 =
231 static_cast<uint64_t>(stat.f_bfree) * stat.f_frsize;
232 }
233
234 *total_size_kb = static_cast<size_t>(total_size_uint64 / 1024);
235 *remaining_size_kb = static_cast<size_t>(remaining_size_uint64 / 1024);
236 }
237
238 virtual void FormatUnmountedDevice(const char* file_path) OVERRIDE {
239 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
240 for (MountLibrary::DiskMap::iterator it = disks_.begin();
241 it != disks_.end(); ++it) {
242 if (it->second->file_path().compare(file_path) == 0 &&
243 !it->second->mount_path().empty()) {
244 OnFormatDevice(file_path,
245 false,
246 MOUNT_METHOD_ERROR_LOCAL,
247 "Device is still mounted.");
248 return;
249 }
250 }
251 libcros_proxy_->CallFormatDevice(file_path, "vfat", &FormatDeviceCallback,
252 this);
253 }
254
255 virtual void FormatMountedDevice(const char* mount_path) OVERRIDE {
256 DCHECK(mount_path);
257 Disk* disk = NULL;
258 for (MountLibrary::DiskMap::iterator it = disks_.begin();
259 it != disks_.end(); ++it) {
260 if (it->second->mount_path().compare(mount_path) == 0) {
261 disk = it->second;
262 break;
263 }
264 }
265 if (!disk) {
266 OnFormatDevice(mount_path,
267 false,
268 MOUNT_METHOD_ERROR_LOCAL,
269 "Device with this mount path not found.");
270 return;
271 }
272
273 if (formatting_pending_.find(disk->device_path()) !=
274 formatting_pending_.end()) {
275 OnFormatDevice(mount_path,
276 false,
277 MOUNT_METHOD_ERROR_LOCAL,
278 "Formatting is already pending.");
279 return;
280 }
281 // Formatting process continues, after unmounting.
282 formatting_pending_[disk->device_path()] = disk->file_path();
283 UnmountPath(disk->mount_path().c_str());
284 }
285
286 virtual void UnmountDeviceRecursive(const char* device_path,
287 UnmountDeviceRecursiveCallbackType callback, void* user_data)
288 OVERRIDE {
289 bool success = true;
290 const char* error_message = NULL;
291 std::vector<const char*> devices_to_unmount;
292
293 // Get list of all devices to unmount.
294 int device_path_len = strlen(device_path);
295 for (DiskMap::iterator it = disks_.begin(); it != disks_.end(); ++it) {
296 if (!it->second->mount_path().empty() &&
297 strncmp(device_path, it->second->device_path().c_str(),
298 device_path_len) == 0) {
299 devices_to_unmount.push_back(it->second->mount_path().c_str());
300 }
301 }
302
303 // We should detect at least original device.
304 if (devices_to_unmount.size() == 0) {
305 if (disks_.find(device_path) == disks_.end()) {
306 success = false;
307 error_message = kDeviceNotFound;
308 } else {
309 // Nothing to unmount.
310 callback(user_data, true);
311 return;
312 }
313 }
314
315 if (success) {
316 // We will send the same callback data object to all Unmount calls and use
317 // it to syncronize callbacks.
318 UnmountDeviceRecursiveCallbackData*
319 cb_data = new UnmountDeviceRecursiveCallbackData(this, user_data,
320 callback, devices_to_unmount.size());
321 for (std::vector<const char*>::iterator it = devices_to_unmount.begin();
322 it != devices_to_unmount.end();
323 ++it) {
324 libcros_proxy_->CallUnmountPath(*it, &UnmountDeviceRecursiveCallback,
325 cb_data);
326 }
327 } else {
328 LOG(WARNING) << "Unmount recursive request failed for device "
329 << device_path << ", with error: " << error_message;
330 callback(user_data, false);
331 }
332 }
333
334 virtual void RequestMountInfoRefresh() OVERRIDE {
335 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
336 libcros_proxy_->CallRequestMountInfo(RequestMountInfoCallback, this);
337 }
338
339 const DiskMap& disks() const OVERRIDE { return disks_; }
340 const MountPointMap& mount_points() const OVERRIDE { return mount_points_; }
341
342 virtual void SetLibcrosProxy(MountLibcrosProxy* proxy) OVERRIDE {
343 libcros_proxy_->DisconnectCrosDisksMonitorIfSet(mount_status_connection_);
344 libcros_proxy_.reset(proxy);
345 mount_status_connection_ = libcros_proxy_->MonitorCrosDisks(
346 &MonitorMountEventsHandler, &MountCompletedHandler, this);
347 }
348 private:
349 // Callback for MountComplete signal and MountSourcePath method.
350 static void MountCompletedHandler(void* object,
351 MountError error_code,
352 const char* source_path,
353 MountType type,
354 const char* mount_path) {
355 DCHECK(object);
356 MountCondition mount_condition = MOUNT_CONDITION_NONE;
357 if (type == MOUNT_TYPE_DEVICE) {
358 if (error_code == MOUNT_ERROR_UNKNOWN_FILESYSTEM)
359 mount_condition = MOUNT_CONDITION_UNKNOWN_FILESYSTEM;
360 if (error_code == MOUNT_ERROR_UNSUPORTED_FILESYSTEM)
361 mount_condition = MOUNT_CONDITION_UNSUPPORTED_FILESYSTEM;
362 }
363
364 MountLibraryImpl* self = static_cast<MountLibraryImpl*>(object);
365 self->OnMountCompleted(static_cast<MountError>(error_code),
366 MountPointInfo(source_path,
367 mount_path,
368 type,
369 mount_condition));
370 }
371
372 // Callback for UnmountRemovableDevice method.
373 static void UnmountMountPointCallback(void* object,
374 const char* mount_path,
375 MountMethodErrorType error,
376 const char* error_message) {
377 DCHECK(object);
378 MountLibraryImpl* self = static_cast<MountLibraryImpl*>(object);
379 self->OnUnmountPath(mount_path, error, error_message);
380 }
381
382 // Callback for FormatRemovableDevice method.
383 static void FormatDeviceCallback(void* object,
384 const char* file_path,
385 bool success,
386 MountMethodErrorType error,
387 const char* error_message) {
388 DCHECK(object);
389 MountLibraryImpl* self = static_cast<MountLibraryImpl*>(object);
390 const char* device_path = self->FilePathToDevicePath(file_path);
391 if (!device_path) {
392 LOG(ERROR) << "Error while handling disks metadata. Cannot find "
393 << "device that is being formatted.";
394 return;
395 }
396 self->OnFormatDevice(device_path, success, error, error_message);
397 }
398
399 // Callback for UnmountDeviceRecursive.
400 static void UnmountDeviceRecursiveCallback(void* object,
401 const char* mount_path,
402 MountMethodErrorType error,
403 const char* error_message) {
404 DCHECK(object);
405 UnmountDeviceRecursiveCallbackData* cb_data =
406 static_cast<UnmountDeviceRecursiveCallbackData*>(object);
407
408 // Do standard processing for Unmount event.
409 cb_data->object->OnUnmountPath(mount_path,
410 error,
411 error_message);
412 if (error == MOUNT_METHOD_ERROR_LOCAL) {
413 cb_data->success = false;
414 } else if (error == MOUNT_METHOD_ERROR_NONE) {
415 LOG(INFO) << mount_path << " unmounted.";
416 }
417
418 // This is safe as long as all callbacks are called on the same thread as
419 // UnmountDeviceRecursive.
420 cb_data->pending_callbacks_count--;
421
422 if (cb_data->pending_callbacks_count == 0) {
423 cb_data->callback(cb_data->user_data, cb_data->success);
424 delete cb_data;
425 }
426 }
427
428 // Callback for disk information retrieval calls.
429 static void GetDiskPropertiesCallback(void* object,
430 const char* device_path,
431 const DiskInfo* disk,
432 MountMethodErrorType error,
433 const char* error_message) {
434 DCHECK(object);
435 MountLibraryImpl* self = static_cast<MountLibraryImpl*>(object);
436 self->OnGetDiskProperties(device_path,
437 disk,
438 error,
439 error_message);
440 }
441
442 // Callback for RequestMountInfo call.
443 static void RequestMountInfoCallback(void* object,
444 const char** devices,
445 size_t device_len,
446 MountMethodErrorType error,
447 const char* error_message) {
448 DCHECK(object);
449 MountLibraryImpl* self = static_cast<MountLibraryImpl*>(object);
450 self->OnRequestMountInfo(devices,
451 device_len,
452 error,
453 error_message);
454 }
455
456 // This method will receive events that are caused by drive status changes.
457 static void MonitorMountEventsHandler(void* object,
458 MountEventType evt,
459 const char* device_path) {
460 DCHECK(object);
461 MountLibraryImpl* self = static_cast<MountLibraryImpl*>(object);
462 self->OnMountEvent(evt, device_path);
463 }
464
465
466 void OnMountCompleted(MountError error_code,
467 const MountPointInfo& mount_info) {
468 DCHECK(!mount_info.source_path.empty());
469
470 FireMountCompleted(MOUNTING, error_code, mount_info);
471
472 // If the device is corrupted but it's still possible to format it, it will
473 // be fake mounted.
474 if ((error_code == MOUNT_ERROR_NONE || mount_info.mount_condition) &&
475 mount_points_.find(mount_info.mount_path) == mount_points_.end()) {
476 mount_points_.insert(MountPointMap::value_type(
477 mount_info.mount_path.c_str(),
478 mount_info));
479 }
480
481 if ((error_code == MOUNT_ERROR_NONE || mount_info.mount_condition) &&
482 mount_info.mount_type == MOUNT_TYPE_DEVICE &&
483 !mount_info.source_path.empty() &&
484 !mount_info.mount_path.empty()) {
485 DiskMap::iterator iter = disks_.find(mount_info.source_path);
486 if (iter == disks_.end()) {
487 // disk might have been removed by now?
488 return;
489 }
490 Disk* disk = iter->second;
491 DCHECK(disk);
492 disk->set_mount_path(mount_info.mount_path.c_str());
493 FireDiskStatusUpdate(MOUNT_DISK_MOUNTED, disk);
494 }
495 }
496
497 void OnUnmountPath(const char* mount_path,
498 MountMethodErrorType error,
499 const char* error_message) {
500 DCHECK(mount_path);
501 if (error == MOUNT_METHOD_ERROR_NONE && mount_path) {
502 MountPointMap::iterator mount_points_it = mount_points_.find(mount_path);
503 if (mount_points_it == mount_points_.end())
504 return;
505 // TODO(tbarzic): Add separate, PathUnmounted event to Observer.
506 FireMountCompleted(
507 UNMOUNTING,
508 MOUNT_ERROR_NONE,
509 MountPointInfo(mount_points_it->second.source_path.c_str(),
510 mount_points_it->second.mount_path.c_str(),
511 mount_points_it->second.mount_type,
512 mount_points_it->second.mount_condition));
513 std::string path(mount_points_it->second.source_path);
514 mount_points_.erase(mount_points_it);
515 DiskMap::iterator iter = disks_.find(path);
516 if (iter == disks_.end()) {
517 // disk might have been removed by now.
518 return;
519 }
520 Disk* disk = iter->second;
521 DCHECK(disk);
522 disk->clear_mount_path();
523 // Check if there is a formatting scheduled
524 PathMap::iterator it = formatting_pending_.find(disk->device_path());
525 if (it != formatting_pending_.end()) {
526 const std::string file_path = it->second;
527 formatting_pending_.erase(it);
528 FormatUnmountedDevice(file_path.c_str());
529 }
530 } else {
531 LOG(WARNING) << "Unmount request failed for device "
532 << mount_path << ", with error: "
533 << (error_message ? error_message : "Unknown");
534 }
535 }
536
537 void OnFormatDevice(const char* device_path,
538 bool success,
539 MountMethodErrorType error,
540 const char* error_message) {
541 DCHECK(device_path);
542 if (error == MOUNT_METHOD_ERROR_NONE && device_path && success) {
543 FireDeviceStatusUpdate(MOUNT_FORMATTING_STARTED, device_path);
544 } else {
545 FireDeviceStatusUpdate(MOUNT_FORMATTING_STARTED,
546 std::string("!") + device_path);
547 LOG(WARNING) << "Format request failed for device "
548 << device_path << ", with error: "
549 << (error_message ? error_message : "Unknown");
550 }
551 }
552
553 void OnGetDiskProperties(const char* device_path,
554 const DiskInfo* disk,
555 MountMethodErrorType error,
556 const char* error_message) {
557 DCHECK(device_path);
558 if (error == MOUNT_METHOD_ERROR_NONE && device_path) {
559 // TODO(zelidrag): Find a better way to filter these out before we
560 // fetch the properties:
561 // Ignore disks coming from the device we booted the system from.
562
563 // This cast is temporal solution, until we merge DiskInfo and
564 // DiskInfoAdvanced into single interface.
565 if (disk->on_boot_device())
566 return;
567
568 LOG(WARNING) << "Found disk " << device_path;
569 // Delete previous disk info for this path:
570 bool is_new = true;
571 std::string device_path_string(device_path);
572 DiskMap::iterator iter = disks_.find(device_path_string);
573 if (iter != disks_.end()) {
574 delete iter->second;
575 disks_.erase(iter);
576 is_new = false;
577 }
578
579 std::string path;
580 std::string mountpath;
581 std::string systempath;
582 std::string filepath;
583 std::string devicelabel;
584 std::string drivelabel;
585 std::string parentpath;
586
587 if (disk->path() != NULL)
588 path = disk->path();
589
590 if (disk->mount_path() != NULL)
591 mountpath = disk->mount_path();
592
593 if (disk->system_path() != NULL)
594 systempath = disk->system_path();
595
596 if (disk->file_path() != NULL)
597 filepath = disk->file_path();
598
599 if (disk->label() != NULL)
600 devicelabel = disk->label();
601
602 if (disk->drive_label() != NULL)
603 drivelabel = disk->drive_label();
604
605 if (disk->partition_slave() != NULL)
606 parentpath = disk->partition_slave();
607
608 Disk* new_disk = new Disk(path,
609 mountpath,
610 systempath,
611 filepath,
612 devicelabel,
613 drivelabel,
614 parentpath,
615 FindSystemPathPrefix(systempath),
616 disk->device_type(),
617 disk->size(),
618 disk->is_drive(),
619 disk->is_read_only(),
620 disk->has_media(),
621 disk->on_boot_device(),
622 disk->is_hidden());
623 disks_.insert(
624 std::pair<std::string, Disk*>(device_path_string, new_disk));
625 FireDiskStatusUpdate(is_new ? MOUNT_DISK_ADDED : MOUNT_DISK_CHANGED,
626 new_disk);
627 } else {
628 LOG(WARNING) << "Property retrieval request failed for device "
629 << device_path << ", with error: "
630 << (error_message ? error_message : "Unknown");
631 }
632 }
633
634 void OnRequestMountInfo(const char** devices,
635 size_t devices_len,
636 MountMethodErrorType error,
637 const char* error_message) {
638 std::set<std::string> current_device_set;
639 if (error == MOUNT_METHOD_ERROR_NONE && devices && devices_len) {
640 // Initiate properties fetch for all removable disks,
641 for (size_t i = 0; i < devices_len; i++) {
642 if (!devices[i]) {
643 NOTREACHED();
644 continue;
645 }
646 current_device_set.insert(std::string(devices[i]));
647 // Initiate disk property retrieval for each relevant device path.
648 libcros_proxy_->CallGetDiskProperties(devices[i],
649 &GetDiskPropertiesCallback, this);
650 }
651 } else if (error != MOUNT_METHOD_ERROR_NONE) {
652 LOG(WARNING) << "Request mount info retrieval request failed with error: "
653 << (error_message ? error_message : "Unknown");
654 }
655 // Search and remove disks that are no longer present.
656 for (MountLibrary::DiskMap::iterator iter = disks_.begin();
657 iter != disks_.end(); ) {
658 if (current_device_set.find(iter->first) == current_device_set.end()) {
659 Disk* disk = iter->second;
660 FireDiskStatusUpdate(MOUNT_DISK_REMOVED, disk);
661 delete iter->second;
662 disks_.erase(iter++);
663 } else {
664 ++iter;
665 }
666 }
667 }
668
669 void OnMountEvent(MountEventType evt,
670 const char* device_path) {
671 if (!device_path)
672 return;
673 MountLibraryEventType type = MOUNT_DEVICE_ADDED;
674 switch (evt) {
675 case DISK_ADDED: {
676 libcros_proxy_->CallGetDiskProperties(device_path,
677 &MountLibraryImpl::GetDiskPropertiesCallback, this);
678 return;
679 }
680 case DISK_REMOVED: {
681 // Search and remove disks that are no longer present.
682 MountLibrary::DiskMap::iterator iter =
683 disks_.find(std::string(device_path));
684 if (iter != disks_.end()) {
685 Disk* disk = iter->second;
686 FireDiskStatusUpdate(MOUNT_DISK_REMOVED, disk);
687 delete iter->second;
688 disks_.erase(iter);
689 }
690 return;
691 }
692 case DEVICE_ADDED: {
693 type = MOUNT_DEVICE_ADDED;
694 system_path_prefixes_.insert(device_path);
695 break;
696 }
697 case DEVICE_REMOVED: {
698 type = MOUNT_DEVICE_REMOVED;
699 system_path_prefixes_.erase(device_path);
700 break;
701 }
702 case DEVICE_SCANNED: {
703 type = MOUNT_DEVICE_SCANNED;
704 break;
705 }
706 case FORMATTING_FINISHED: {
707 // FORMATTING_FINISHED actually returns file path instead of device
708 // path.
709 device_path = FilePathToDevicePath(device_path);
710 if (!device_path) {
711 LOG(ERROR) << "Error while handling disks metadata. Cannot find "
712 << "device that is being formatted.";
713 return;
714 }
715 type = MOUNT_FORMATTING_FINISHED;
716 break;
717 }
718 default: {
719 return;
720 }
721 }
722 FireDeviceStatusUpdate(type, std::string(device_path));
723 }
724
725 void FireDiskStatusUpdate(MountLibraryEventType evt,
726 const Disk* disk) {
727 // Make sure we run on UI thread.
728 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
729 FOR_EACH_OBSERVER(
730 Observer, observers_, DiskChanged(evt, disk));
731 }
732
733 void FireDeviceStatusUpdate(MountLibraryEventType evt,
734 const std::string& device_path) {
735 // Make sure we run on UI thread.
736 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
737 FOR_EACH_OBSERVER(
738 Observer, observers_, DeviceChanged(evt, device_path));
739 }
740
741 void FireMountCompleted(MountEvent event_type,
742 MountError error_code,
743 const MountPointInfo& mount_info) {
744 // Make sure we run on UI thread.
745 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
746 FOR_EACH_OBSERVER(
747 Observer, observers_, MountCompleted(event_type,
748 error_code,
749 mount_info));
750 }
751
752 const char* FilePathToDevicePath(const char* file_path) {
753 int failed = (file_path[0] == '!') ? 1 : 0;
754 for (MountLibrary::DiskMap::iterator it = disks_.begin();
755 it != disks_.end(); ++it) {
756 if (it->second->file_path().compare(file_path + failed) == 0) {
757 if (failed) {
758 return (std::string("!") + it->second->device_path()).c_str();
759 } else {
760 return it->second->device_path().c_str();
761 }
762 }
763 }
764 return NULL;
765 }
766
767 const std::string& FindSystemPathPrefix(const std::string& system_path) {
768 if (system_path.empty())
769 return EmptyString();
770 for (SystemPathPrefixSet::const_iterator it = system_path_prefixes_.begin();
771 it != system_path_prefixes_.end();
772 ++it) {
773 if (system_path.find(*it, 0) == 0)
774 return *it;
775 }
776 return EmptyString();
777 }
778
779 // Mount event change observers.
780 ObserverList<Observer> observers_;
781
782 scoped_ptr<MountLibcrosProxy> libcros_proxy_;
783
784 // A reference to the mount api, to allow callbacks when the mount
785 // status changes.
786 MountEventConnection mount_status_connection_;
787
788 // The list of disks found.
789 MountLibrary::DiskMap disks_;
790
791 MountLibrary::MountPointMap mount_points_;
792
793 typedef std::set<std::string> SystemPathPrefixSet;
794 SystemPathPrefixSet system_path_prefixes_;
795
796 // Set of devices that are supposed to be formated, but are currently waiting
797 // to be unmounted. When device is in this map, the formatting process HAVEN'T
798 // started yet.
799 PathMap formatting_pending_;
800
801 DISALLOW_COPY_AND_ASSIGN(MountLibraryImpl);
802 };
803
804 class MountLibraryStubImpl : public MountLibrary {
805 public:
806 MountLibraryStubImpl() {}
807 virtual ~MountLibraryStubImpl() {}
808
809 // MountLibrary overrides.
810 virtual void Init() OVERRIDE {}
811 virtual void AddObserver(Observer* observer) OVERRIDE {}
812 virtual void RemoveObserver(Observer* observer) OVERRIDE {}
813 virtual const DiskMap& disks() const OVERRIDE { return disks_; }
814 virtual const MountPointMap& mount_points() const OVERRIDE {
815 return mount_points_;
816 }
817 virtual void RequestMountInfoRefresh() OVERRIDE {}
818 virtual void MountPath(const char* source_path, MountType type,
819 const MountPathOptions& options) OVERRIDE {}
820 virtual void UnmountPath(const char* mount_path) OVERRIDE {}
821 virtual void GetSizeStatsOnFileThread(const char* mount_path,
822 size_t* total_size_kb, size_t* remaining_size_kb) OVERRIDE {}
823 virtual void FormatUnmountedDevice(const char* device_path) OVERRIDE {}
824 virtual void FormatMountedDevice(const char* mount_path) OVERRIDE {}
825 virtual void UnmountDeviceRecursive(const char* device_path,
826 UnmountDeviceRecursiveCallbackType callback, void* user_data)
827 OVERRIDE {}
828 private:
829 // The list of disks found.
830 DiskMap disks_;
831 MountPointMap mount_points_;
832
833 DISALLOW_COPY_AND_ASSIGN(MountLibraryStubImpl);
834 };
835
836 // static
837 MountLibrary* MountLibrary::GetImpl(bool stub) {
838 MountLibrary* impl;
839 if (stub)
840 impl = new MountLibraryStubImpl();
841 else
842 impl = new MountLibraryImpl();
843 impl->Init();
844 return impl;
845 }
846
847 } // namespace chromeos
OLDNEW
« no previous file with comments | « chrome/browser/chromeos/cros/mount_library.h ('k') | chrome/chrome_browser.gypi » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698