1 // Copyright 2013 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/file_manager/volume_manager.h" 6 7 #include <string> 8 #include <vector> 9 10 #include "base/basictypes.h" 11 #include "base/prefs/pref_service.h" 12 #include "base/strings/utf_string_conversions.h" 13 #include "chrome/browser/chromeos/file_manager/fake_disk_mount_manager.h" 14 #include "chrome/browser/chromeos/file_manager/volume_manager_observer.h" 15 #include "chrome/browser/chromeos/file_system_provider/fake_provided_file_system.h" 16 #include "chrome/browser/chromeos/file_system_provider/service.h" 17 #include "chrome/common/pref_names.h" 18 #include "chrome/test/base/testing_profile.h" 19 #include "chromeos/dbus/fake_power_manager_client.h" 20 #include "chromeos/disks/disk_mount_manager.h" 21 #include "components/storage_monitor/storage_info.h" 22 #include "content/public/test/test_browser_thread_bundle.h" 23 #include "extensions/browser/extension_registry.h" 24 #include "testing/gtest/include/gtest/gtest.h" 25 26 namespace file_manager { 27 namespace { 28 29 class LoggingObserver : public VolumeManagerObserver { 30 public: 31 struct Event { 32 enum EventType { 33 DISK_ADDED, 34 DISK_REMOVED, 35 DEVICE_ADDED, 36 DEVICE_REMOVED, 37 VOLUME_MOUNTED, 38 VOLUME_UNMOUNTED, 39 FORMAT_STARTED, 40 FORMAT_COMPLETED, 41 } type; 42 43 // Available on DEVICE_ADDED, DEVICE_REMOVED, VOLUME_MOUNTED, 44 // VOLUME_UNMOUNTED, FORMAT_STARTED and FORMAT_COMPLETED. 45 std::string device_path; 46 47 // Available on DISK_ADDED. 48 bool mounting; 49 50 // Available on DEVICE_REMOVED; 51 bool hard_unplugged; 52 53 // Available on VOLUME_MOUNTED and VOLUME_UNMOUNTED. 54 chromeos::MountError mount_error; 55 56 // Available on VOLUME_MOUNTED. 57 bool is_remounting; 58 59 // Available on FORMAT_STARTED and FORMAT_COMPLETED. 60 bool success; 61 }; 62 63 LoggingObserver() {} 64 virtual ~LoggingObserver() {} 65 66 const std::vector<Event>& events() const { return events_; } 67 68 // VolumeManagerObserver overrides. 69 virtual void OnDiskAdded(const chromeos::disks::DiskMountManager::Disk& disk, 70 bool mounting) OVERRIDE { 71 Event event; 72 event.type = Event::DISK_ADDED; 73 event.device_path = disk.device_path(); // Keep only device_path. 74 event.mounting = mounting; 75 events_.push_back(event); 76 } 77 78 virtual void OnDiskRemoved( 79 const chromeos::disks::DiskMountManager::Disk& disk) OVERRIDE { 80 Event event; 81 event.type = Event::DISK_REMOVED; 82 event.device_path = disk.device_path(); // Keep only device_path. 83 events_.push_back(event); 84 } 85 86 virtual void OnDeviceAdded(const std::string& device_path) OVERRIDE { 87 Event event; 88 event.type = Event::DEVICE_ADDED; 89 event.device_path = device_path; 90 events_.push_back(event); 91 } 92 93 virtual void OnDeviceRemoved(const std::string& device_path, 94 bool hard_unplugged) OVERRIDE { 95 Event event; 96 event.type = Event::DEVICE_REMOVED; 97 event.device_path = device_path; 98 event.hard_unplugged = hard_unplugged; 99 events_.push_back(event); 100 } 101 102 virtual void OnVolumeMounted(chromeos::MountError error_code, 103 const VolumeInfo& volume_info, 104 bool is_remounting) OVERRIDE { 105 Event event; 106 event.type = Event::VOLUME_MOUNTED; 107 event.device_path = volume_info.source_path.AsUTF8Unsafe(); 108 event.mount_error = error_code; 109 event.is_remounting = is_remounting; 110 events_.push_back(event); 111 } 112 113 virtual void OnVolumeUnmounted(chromeos::MountError error_code, 114 const VolumeInfo& volume_info) OVERRIDE { 115 Event event; 116 event.type = Event::VOLUME_UNMOUNTED; 117 event.device_path = volume_info.source_path.AsUTF8Unsafe(); 118 event.mount_error = error_code; 119 events_.push_back(event); 120 } 121 122 virtual void OnFormatStarted( 123 const std::string& device_path, bool success) OVERRIDE { 124 Event event; 125 event.type = Event::FORMAT_STARTED; 126 event.device_path = device_path; 127 event.success = success; 128 events_.push_back(event); 129 } 130 131 virtual void OnFormatCompleted( 132 const std::string& device_path, bool success) OVERRIDE { 133 Event event; 134 event.type = Event::FORMAT_COMPLETED; 135 event.device_path = device_path; 136 event.success = success; 137 events_.push_back(event); 138 } 139 140 private: 141 std::vector<Event> events_; 142 143 DISALLOW_COPY_AND_ASSIGN(LoggingObserver); 144 }; 145 146 } // namespace 147 148 class VolumeManagerTest : public testing::Test { 149 protected: 150 // Helper class that contains per-profile objects. 151 class ProfileEnvironment { 152 public: 153 ProfileEnvironment(chromeos::PowerManagerClient* power_manager_client, 154 chromeos::disks::DiskMountManager* disk_manager) 155 : profile_(new TestingProfile), 156 extension_registry_( 157 new extensions::ExtensionRegistry(profile_.get())), 158 file_system_provider_service_( 159 new chromeos::file_system_provider::Service( 160 profile_.get(), 161 extension_registry_.get())), 162 volume_manager_( 163 new VolumeManager(profile_.get(), 164 NULL, // DriveIntegrationService 165 power_manager_client, 166 disk_manager, 167 file_system_provider_service_.get())) { 168 file_system_provider_service_->SetFileSystemFactoryForTesting(base::Bind( 169 &chromeos::file_system_provider::FakeProvidedFileSystem::Create)); 170 } 171 172 Profile* profile() const { return profile_.get(); } 173 VolumeManager* volume_manager() const { return volume_manager_.get(); } 174 175 private: 176 scoped_ptr<TestingProfile> profile_; 177 scoped_ptr<extensions::ExtensionRegistry> extension_registry_; 178 scoped_ptr<chromeos::file_system_provider::Service> 179 file_system_provider_service_; 180 scoped_ptr<VolumeManager> volume_manager_; 181 }; 182 183 virtual void SetUp() OVERRIDE { 184 power_manager_client_.reset(new chromeos::FakePowerManagerClient); 185 disk_mount_manager_.reset(new FakeDiskMountManager); 186 main_profile_.reset(new ProfileEnvironment(power_manager_client_.get(), 187 disk_mount_manager_.get())); 188 } 189 190 Profile* profile() const { return main_profile_->profile(); } 191 VolumeManager* volume_manager() const { 192 return main_profile_->volume_manager(); 193 } 194 195 content::TestBrowserThreadBundle thread_bundle_; 196 scoped_ptr<chromeos::FakePowerManagerClient> power_manager_client_; 197 scoped_ptr<FakeDiskMountManager> disk_mount_manager_; 198 scoped_ptr<ProfileEnvironment> main_profile_; 199 }; 200 201 TEST_F(VolumeManagerTest, OnDriveFileSystemMountAndUnmount) { 202 LoggingObserver observer; 203 volume_manager()->AddObserver(&observer); 204 205 volume_manager()->OnFileSystemMounted(); 206 207 ASSERT_EQ(1U, observer.events().size()); 208 LoggingObserver::Event event = observer.events()[0]; 209 EXPECT_EQ(LoggingObserver::Event::VOLUME_MOUNTED, event.type); 210 EXPECT_EQ(drive::util::GetDriveMountPointPath(profile()).AsUTF8Unsafe(), 211 event.device_path); 212 EXPECT_EQ(chromeos::MOUNT_ERROR_NONE, event.mount_error); 213 EXPECT_FALSE(event.is_remounting); 214 215 volume_manager()->OnFileSystemBeingUnmounted(); 216 217 ASSERT_EQ(2U, observer.events().size()); 218 event = observer.events()[1]; 219 EXPECT_EQ(LoggingObserver::Event::VOLUME_UNMOUNTED, event.type); 220 EXPECT_EQ(drive::util::GetDriveMountPointPath(profile()).AsUTF8Unsafe(), 221 event.device_path); 222 EXPECT_EQ(chromeos::MOUNT_ERROR_NONE, event.mount_error); 223 224 volume_manager()->RemoveObserver(&observer); 225 } 226 227 TEST_F(VolumeManagerTest, OnDriveFileSystemUnmountWithoutMount) { 228 LoggingObserver observer; 229 volume_manager()->AddObserver(&observer); 230 volume_manager()->OnFileSystemBeingUnmounted(); 231 232 // Unmount event for non-mounted volume is not reported. 233 ASSERT_EQ(0U, observer.events().size()); 234 volume_manager()->RemoveObserver(&observer); 235 } 236 237 TEST_F(VolumeManagerTest, OnDiskEvent_Hidden) { 238 LoggingObserver observer; 239 volume_manager()->AddObserver(&observer); 240 241 const bool kIsHidden = true; 242 const chromeos::disks::DiskMountManager::Disk kDisk( 243 "device1", "", "", "", "", "", "", "", "", "", "", "", 244 chromeos::DEVICE_TYPE_UNKNOWN, 0, false, false, false, false, kIsHidden); 245 246 volume_manager()->OnDiskEvent( 247 chromeos::disks::DiskMountManager::DISK_ADDED, &kDisk); 248 EXPECT_EQ(0U, observer.events().size()); 249 250 volume_manager()->OnDiskEvent( 251 chromeos::disks::DiskMountManager::DISK_REMOVED, &kDisk); 252 EXPECT_EQ(0U, observer.events().size()); 253 254 volume_manager()->OnDiskEvent( 255 chromeos::disks::DiskMountManager::DISK_CHANGED, &kDisk); 256 EXPECT_EQ(0U, observer.events().size()); 257 258 volume_manager()->RemoveObserver(&observer); 259 } 260 261 TEST_F(VolumeManagerTest, OnDiskEvent_Added) { 262 // Enable external storage. 263 profile()->GetPrefs()->SetBoolean(prefs::kExternalStorageDisabled, false); 264 265 LoggingObserver observer; 266 volume_manager()->AddObserver(&observer); 267 268 const chromeos::disks::DiskMountManager::Disk kEmptyDevicePathDisk( 269 "", // empty device path. 270 "", "", "", "", "", "", "", "", "", "", "", 271 chromeos::DEVICE_TYPE_UNKNOWN, 0, false, false, false, false, false); 272 volume_manager()->OnDiskEvent( 273 chromeos::disks::DiskMountManager::DISK_ADDED, &kEmptyDevicePathDisk); 274 EXPECT_EQ(0U, observer.events().size()); 275 276 const bool kHasMedia = true; 277 const chromeos::disks::DiskMountManager::Disk kMediaDisk( 278 "device1", "", "", "", "", "", "", "", "", "", "", "", 279 chromeos::DEVICE_TYPE_UNKNOWN, 0, false, false, kHasMedia, false, false); 280 volume_manager()->OnDiskEvent( 281 chromeos::disks::DiskMountManager::DISK_ADDED, &kMediaDisk); 282 ASSERT_EQ(1U, observer.events().size()); 283 const LoggingObserver::Event& event = observer.events()[0]; 284 EXPECT_EQ(LoggingObserver::Event::DISK_ADDED, event.type); 285 EXPECT_EQ("device1", event.device_path); 286 EXPECT_TRUE(event.mounting); 287 288 ASSERT_EQ(1U, disk_mount_manager_->mount_requests().size()); 289 const FakeDiskMountManager::MountRequest& mount_request = 290 disk_mount_manager_->mount_requests()[0]; 291 EXPECT_EQ("device1", mount_request.source_path); 292 EXPECT_EQ("", mount_request.source_format); 293 EXPECT_EQ("", mount_request.mount_label); 294 EXPECT_EQ(chromeos::MOUNT_TYPE_DEVICE, mount_request.type); 295 296 volume_manager()->RemoveObserver(&observer); 297 } 298 299 TEST_F(VolumeManagerTest, OnDiskEvent_AddedNonMounting) { 300 // Enable external storage. 301 profile()->GetPrefs()->SetBoolean(prefs::kExternalStorageDisabled, false); 302 303 // Device which is already mounted. 304 { 305 LoggingObserver observer; 306 volume_manager()->AddObserver(&observer); 307 308 const bool kHasMedia = true; 309 const chromeos::disks::DiskMountManager::Disk kMountedMediaDisk( 310 "device1", "mounted", "", "", "", "", "", "", "", "", "", "", 311 chromeos::DEVICE_TYPE_UNKNOWN, 0, false, false, 312 kHasMedia, false, false); 313 volume_manager()->OnDiskEvent( 314 chromeos::disks::DiskMountManager::DISK_ADDED, &kMountedMediaDisk); 315 ASSERT_EQ(1U, observer.events().size()); 316 const LoggingObserver::Event& event = observer.events()[0]; 317 EXPECT_EQ(LoggingObserver::Event::DISK_ADDED, event.type); 318 EXPECT_EQ("device1", event.device_path); 319 EXPECT_FALSE(event.mounting); 320 321 ASSERT_EQ(0U, disk_mount_manager_->mount_requests().size()); 322 323 volume_manager()->RemoveObserver(&observer); 324 } 325 326 // Device without media. 327 { 328 LoggingObserver observer; 329 volume_manager()->AddObserver(&observer); 330 331 const bool kWithoutMedia = false; 332 const chromeos::disks::DiskMountManager::Disk kNoMediaDisk( 333 "device1", "", "", "", "", "", "", "", "", "", "", "", 334 chromeos::DEVICE_TYPE_UNKNOWN, 0, false, false, 335 kWithoutMedia, false, false); 336 volume_manager()->OnDiskEvent( 337 chromeos::disks::DiskMountManager::DISK_ADDED, &kNoMediaDisk); 338 ASSERT_EQ(1U, observer.events().size()); 339 const LoggingObserver::Event& event = observer.events()[0]; 340 EXPECT_EQ(LoggingObserver::Event::DISK_ADDED, event.type); 341 EXPECT_EQ("device1", event.device_path); 342 EXPECT_FALSE(event.mounting); 343 344 ASSERT_EQ(0U, disk_mount_manager_->mount_requests().size()); 345 346 volume_manager()->RemoveObserver(&observer); 347 } 348 349 // External storage is disabled. 350 { 351 profile()->GetPrefs()->SetBoolean(prefs::kExternalStorageDisabled, true); 352 353 LoggingObserver observer; 354 volume_manager()->AddObserver(&observer); 355 356 const bool kHasMedia = true; 357 const chromeos::disks::DiskMountManager::Disk kMediaDisk( 358 "device1", "", "", "", "", "", "", "", "", "", "", "", 359 chromeos::DEVICE_TYPE_UNKNOWN, 0, false, false, 360 kHasMedia, false, false); 361 volume_manager()->OnDiskEvent( 362 chromeos::disks::DiskMountManager::DISK_ADDED, &kMediaDisk); 363 ASSERT_EQ(1U, observer.events().size()); 364 const LoggingObserver::Event& event = observer.events()[0]; 365 EXPECT_EQ(LoggingObserver::Event::DISK_ADDED, event.type); 366 EXPECT_EQ("device1", event.device_path); 367 EXPECT_FALSE(event.mounting); 368 369 ASSERT_EQ(0U, disk_mount_manager_->mount_requests().size()); 370 371 volume_manager()->RemoveObserver(&observer); 372 } 373 } 374 375 TEST_F(VolumeManagerTest, OnDiskEvent_Removed) { 376 LoggingObserver observer; 377 volume_manager()->AddObserver(&observer); 378 379 const chromeos::disks::DiskMountManager::Disk kMountedDisk( 380 "device1", "mount_path", "", "", "", "", "", "", "", "", "", "", 381 chromeos::DEVICE_TYPE_UNKNOWN, 0, false, false, false, false, false); 382 volume_manager()->OnDiskEvent( 383 chromeos::disks::DiskMountManager::DISK_REMOVED, &kMountedDisk); 384 385 ASSERT_EQ(1U, observer.events().size()); 386 const LoggingObserver::Event& event = observer.events()[0]; 387 EXPECT_EQ(LoggingObserver::Event::DISK_REMOVED, event.type); 388 EXPECT_EQ("device1", event.device_path); 389 390 ASSERT_EQ(1U, disk_mount_manager_->unmount_requests().size()); 391 const FakeDiskMountManager::UnmountRequest& unmount_request = 392 disk_mount_manager_->unmount_requests()[0]; 393 EXPECT_EQ("mount_path", unmount_request.mount_path); 394 EXPECT_EQ(chromeos::UNMOUNT_OPTIONS_LAZY, unmount_request.options); 395 396 volume_manager()->RemoveObserver(&observer); 397 } 398 399 TEST_F(VolumeManagerTest, OnDiskEvent_RemovedNotMounted) { 400 LoggingObserver observer; 401 volume_manager()->AddObserver(&observer); 402 403 const chromeos::disks::DiskMountManager::Disk kNotMountedDisk( 404 "device1", "", "", "", "", "", "", "", "", "", "", "", 405 chromeos::DEVICE_TYPE_UNKNOWN, 0, false, false, false, false, false); 406 volume_manager()->OnDiskEvent( 407 chromeos::disks::DiskMountManager::DISK_REMOVED, &kNotMountedDisk); 408 409 ASSERT_EQ(1U, observer.events().size()); 410 const LoggingObserver::Event& event = observer.events()[0]; 411 EXPECT_EQ(LoggingObserver::Event::DISK_REMOVED, event.type); 412 EXPECT_EQ("device1", event.device_path); 413 414 ASSERT_EQ(0U, disk_mount_manager_->unmount_requests().size()); 415 416 volume_manager()->RemoveObserver(&observer); 417 } 418 419 TEST_F(VolumeManagerTest, OnDiskEvent_Changed) { 420 // Changed event should cause mounting (if possible). 421 LoggingObserver observer; 422 volume_manager()->AddObserver(&observer); 423 424 const chromeos::disks::DiskMountManager::Disk kDisk( 425 "device1", "", "", "", "", "", "", "", "", "", "", "", 426 chromeos::DEVICE_TYPE_UNKNOWN, 0, false, false, true, false, false); 427 volume_manager()->OnDiskEvent( 428 chromeos::disks::DiskMountManager::DISK_CHANGED, &kDisk); 429 430 EXPECT_EQ(1U, observer.events().size()); 431 EXPECT_EQ(1U, disk_mount_manager_->mount_requests().size()); 432 EXPECT_EQ(0U, disk_mount_manager_->unmount_requests().size()); 433 434 volume_manager()->RemoveObserver(&observer); 435 } 436 437 TEST_F(VolumeManagerTest, OnDeviceEvent_Added) { 438 LoggingObserver observer; 439 volume_manager()->AddObserver(&observer); 440 441 volume_manager()->OnDeviceEvent( 442 chromeos::disks::DiskMountManager::DEVICE_ADDED, "device1"); 443 444 ASSERT_EQ(1U, observer.events().size()); 445 const LoggingObserver::Event& event = observer.events()[0]; 446 EXPECT_EQ(LoggingObserver::Event::DEVICE_ADDED, event.type); 447 EXPECT_EQ("device1", event.device_path); 448 449 volume_manager()->RemoveObserver(&observer); 450 } 451 452 TEST_F(VolumeManagerTest, OnDeviceEvent_Removed) { 453 LoggingObserver observer; 454 volume_manager()->AddObserver(&observer); 455 456 volume_manager()->OnDeviceEvent( 457 chromeos::disks::DiskMountManager::DEVICE_REMOVED, "device1"); 458 459 ASSERT_EQ(1U, observer.events().size()); 460 const LoggingObserver::Event& event = observer.events()[0]; 461 EXPECT_EQ(LoggingObserver::Event::DEVICE_REMOVED, event.type); 462 EXPECT_EQ("device1", event.device_path); 463 464 volume_manager()->RemoveObserver(&observer); 465 } 466 467 TEST_F(VolumeManagerTest, OnDeviceEvent_Scanned) { 468 LoggingObserver observer; 469 volume_manager()->AddObserver(&observer); 470 471 volume_manager()->OnDeviceEvent( 472 chromeos::disks::DiskMountManager::DEVICE_SCANNED, "device1"); 473 474 // SCANNED event is just ignored. 475 EXPECT_EQ(0U, observer.events().size()); 476 477 volume_manager()->RemoveObserver(&observer); 478 } 479 480 TEST_F(VolumeManagerTest, OnMountEvent_MountingAndUnmounting) { 481 LoggingObserver observer; 482 volume_manager()->AddObserver(&observer); 483 484 const chromeos::disks::DiskMountManager::MountPointInfo kMountPoint( 485 "device1", 486 "mount1", 487 chromeos::MOUNT_TYPE_DEVICE, 488 chromeos::disks::MOUNT_CONDITION_NONE); 489 490 volume_manager()->OnMountEvent(chromeos::disks::DiskMountManager::MOUNTING, 491 chromeos::MOUNT_ERROR_NONE, 492 kMountPoint); 493 494 ASSERT_EQ(1U, observer.events().size()); 495 LoggingObserver::Event event = observer.events()[0]; 496 EXPECT_EQ(LoggingObserver::Event::VOLUME_MOUNTED, event.type); 497 EXPECT_EQ("device1", event.device_path); 498 EXPECT_EQ(chromeos::MOUNT_ERROR_NONE, event.mount_error); 499 EXPECT_FALSE(event.is_remounting); 500 501 volume_manager()->OnMountEvent(chromeos::disks::DiskMountManager::UNMOUNTING, 502 chromeos::MOUNT_ERROR_NONE, 503 kMountPoint); 504 505 ASSERT_EQ(2U, observer.events().size()); 506 event = observer.events()[1]; 507 EXPECT_EQ(LoggingObserver::Event::VOLUME_UNMOUNTED, event.type); 508 EXPECT_EQ("device1", event.device_path); 509 EXPECT_EQ(chromeos::MOUNT_ERROR_NONE, event.mount_error); 510 511 volume_manager()->RemoveObserver(&observer); 512 } 513 514 TEST_F(VolumeManagerTest, OnMountEvent_Remounting) { 515 scoped_ptr<chromeos::disks::DiskMountManager::Disk> disk( 516 new chromeos::disks::DiskMountManager::Disk( 517 "device1", "", "", "", "", "", "", "", "", "", "uuid1", "", 518 chromeos::DEVICE_TYPE_UNKNOWN, 0, 519 false, false, false, false, false)); 520 disk_mount_manager_->AddDiskForTest(disk.release()); 521 disk_mount_manager_->MountPath( 522 "device1", "", "", chromeos::MOUNT_TYPE_DEVICE); 523 524 // Emulate system suspend and then resume. 525 { 526 power_manager_client_->SendSuspendImminent(); 527 power_manager_client_->SendSuspendDone(); 528 529 // After resume, the device is unmounted and then mounted. 530 disk_mount_manager_->UnmountPath( 531 "device1", chromeos::UNMOUNT_OPTIONS_NONE, 532 chromeos::disks::DiskMountManager::UnmountPathCallback()); 533 disk_mount_manager_->MountPath( 534 "device1", "", "", chromeos::MOUNT_TYPE_DEVICE); 535 } 536 537 LoggingObserver observer; 538 volume_manager()->AddObserver(&observer); 539 540 const chromeos::disks::DiskMountManager::MountPointInfo kMountPoint( 541 "device1", 542 "mount1", 543 chromeos::MOUNT_TYPE_DEVICE, 544 chromeos::disks::MOUNT_CONDITION_NONE); 545 546 volume_manager()->OnMountEvent(chromeos::disks::DiskMountManager::MOUNTING, 547 chromeos::MOUNT_ERROR_NONE, 548 kMountPoint); 549 550 ASSERT_EQ(1U, observer.events().size()); 551 const LoggingObserver::Event& event = observer.events()[0]; 552 EXPECT_EQ(LoggingObserver::Event::VOLUME_MOUNTED, event.type); 553 EXPECT_EQ("device1", event.device_path); 554 EXPECT_EQ(chromeos::MOUNT_ERROR_NONE, event.mount_error); 555 EXPECT_TRUE(event.is_remounting); 556 557 volume_manager()->RemoveObserver(&observer); 558 } 559 560 TEST_F(VolumeManagerTest, OnMountEvent_UnmountingWithoutMounting) { 561 LoggingObserver observer; 562 volume_manager()->AddObserver(&observer); 563 564 const chromeos::disks::DiskMountManager::MountPointInfo kMountPoint( 565 "device1", 566 "mount1", 567 chromeos::MOUNT_TYPE_DEVICE, 568 chromeos::disks::MOUNT_CONDITION_NONE); 569 570 volume_manager()->OnMountEvent(chromeos::disks::DiskMountManager::UNMOUNTING, 571 chromeos::MOUNT_ERROR_NONE, 572 kMountPoint); 573 574 // Unmount event for a disk not mounted in this manager is not reported. 575 ASSERT_EQ(0U, observer.events().size()); 576 577 volume_manager()->RemoveObserver(&observer); 578 } 579 580 TEST_F(VolumeManagerTest, OnFormatEvent_Started) { 581 LoggingObserver observer; 582 volume_manager()->AddObserver(&observer); 583 584 volume_manager()->OnFormatEvent( 585 chromeos::disks::DiskMountManager::FORMAT_STARTED, 586 chromeos::FORMAT_ERROR_NONE, 587 "device1"); 588 589 ASSERT_EQ(1U, observer.events().size()); 590 const LoggingObserver::Event& event = observer.events()[0]; 591 EXPECT_EQ(LoggingObserver::Event::FORMAT_STARTED, event.type); 592 EXPECT_EQ("device1", event.device_path); 593 EXPECT_TRUE(event.success); 594 595 volume_manager()->RemoveObserver(&observer); 596 } 597 598 TEST_F(VolumeManagerTest, OnFormatEvent_StartFailed) { 599 LoggingObserver observer; 600 volume_manager()->AddObserver(&observer); 601 602 volume_manager()->OnFormatEvent( 603 chromeos::disks::DiskMountManager::FORMAT_STARTED, 604 chromeos::FORMAT_ERROR_UNKNOWN, 605 "device1"); 606 607 ASSERT_EQ(1U, observer.events().size()); 608 const LoggingObserver::Event& event = observer.events()[0]; 609 EXPECT_EQ(LoggingObserver::Event::FORMAT_STARTED, event.type); 610 EXPECT_EQ("device1", event.device_path); 611 EXPECT_FALSE(event.success); 612 613 volume_manager()->RemoveObserver(&observer); 614 } 615 616 TEST_F(VolumeManagerTest, OnFormatEvent_Completed) { 617 LoggingObserver observer; 618 volume_manager()->AddObserver(&observer); 619 620 volume_manager()->OnFormatEvent( 621 chromeos::disks::DiskMountManager::FORMAT_COMPLETED, 622 chromeos::FORMAT_ERROR_NONE, 623 "device1"); 624 625 ASSERT_EQ(1U, observer.events().size()); 626 const LoggingObserver::Event& event = observer.events()[0]; 627 EXPECT_EQ(LoggingObserver::Event::FORMAT_COMPLETED, event.type); 628 EXPECT_EQ("device1", event.device_path); 629 EXPECT_TRUE(event.success); 630 631 // When "format" is successfully done, VolumeManager requests to mount it. 632 ASSERT_EQ(1U, disk_mount_manager_->mount_requests().size()); 633 const FakeDiskMountManager::MountRequest& mount_request = 634 disk_mount_manager_->mount_requests()[0]; 635 EXPECT_EQ("device1", mount_request.source_path); 636 EXPECT_EQ("", mount_request.source_format); 637 EXPECT_EQ("", mount_request.mount_label); 638 EXPECT_EQ(chromeos::MOUNT_TYPE_DEVICE, mount_request.type); 639 640 volume_manager()->RemoveObserver(&observer); 641 } 642 643 TEST_F(VolumeManagerTest, OnFormatEvent_CompletedFailed) { 644 LoggingObserver observer; 645 volume_manager()->AddObserver(&observer); 646 647 volume_manager()->OnFormatEvent( 648 chromeos::disks::DiskMountManager::FORMAT_COMPLETED, 649 chromeos::FORMAT_ERROR_UNKNOWN, 650 "device1"); 651 652 ASSERT_EQ(1U, observer.events().size()); 653 const LoggingObserver::Event& event = observer.events()[0]; 654 EXPECT_EQ(LoggingObserver::Event::FORMAT_COMPLETED, event.type); 655 EXPECT_EQ("device1", event.device_path); 656 EXPECT_FALSE(event.success); 657 658 EXPECT_EQ(0U, disk_mount_manager_->mount_requests().size()); 659 660 volume_manager()->RemoveObserver(&observer); 661 } 662 663 TEST_F(VolumeManagerTest, OnExternalStorageDisabledChanged) { 664 // Here create two mount points. 665 disk_mount_manager_->MountPath( 666 "mount1", "", "", chromeos::MOUNT_TYPE_DEVICE); 667 disk_mount_manager_->MountPath( 668 "mount2", "", "", chromeos::MOUNT_TYPE_DEVICE); 669 670 // Initially, there are two mount points. 671 ASSERT_EQ(2U, disk_mount_manager_->mount_points().size()); 672 ASSERT_EQ(0U, disk_mount_manager_->unmount_requests().size()); 673 674 // Emulate to set kExternalStorageDisabled to false. 675 profile()->GetPrefs()->SetBoolean(prefs::kExternalStorageDisabled, false); 676 volume_manager()->OnExternalStorageDisabledChanged(); 677 678 // Expect no effects. 679 EXPECT_EQ(2U, disk_mount_manager_->mount_points().size()); 680 EXPECT_EQ(0U, disk_mount_manager_->unmount_requests().size()); 681 682 // Emulate to set kExternalStorageDisabled to true. 683 profile()->GetPrefs()->SetBoolean(prefs::kExternalStorageDisabled, true); 684 volume_manager()->OnExternalStorageDisabledChanged(); 685 686 // The all mount points should be unmounted. 687 EXPECT_EQ(0U, disk_mount_manager_->mount_points().size()); 688 689 EXPECT_EQ(2U, disk_mount_manager_->unmount_requests().size()); 690 const FakeDiskMountManager::UnmountRequest& unmount_request1 = 691 disk_mount_manager_->unmount_requests()[0]; 692 EXPECT_EQ("mount1", unmount_request1.mount_path); 693 694 const FakeDiskMountManager::UnmountRequest& unmount_request2 = 695 disk_mount_manager_->unmount_requests()[1]; 696 EXPECT_EQ("mount2", unmount_request2.mount_path); 697 } 698 699 TEST_F(VolumeManagerTest, ExternalStorageDisabledPolicyMultiProfile) { 700 ProfileEnvironment secondary(power_manager_client_.get(), 701 disk_mount_manager_.get()); 702 volume_manager()->Initialize(); 703 secondary.volume_manager()->Initialize(); 704 705 // Simulates the case that the main profile has kExternalStorageDisabled set 706 // as false, and the secondary profile has the config set to true. 707 profile()->GetPrefs()->SetBoolean(prefs::kExternalStorageDisabled, false); 708 secondary.profile()->GetPrefs()->SetBoolean(prefs::kExternalStorageDisabled, 709 true); 710 711 LoggingObserver main_observer, secondary_observer; 712 volume_manager()->AddObserver(&main_observer); 713 secondary.volume_manager()->AddObserver(&secondary_observer); 714 715 // Add 1 disk. 716 const chromeos::disks::DiskMountManager::Disk kMediaDisk( 717 "device1", "", "", "", "", "", "", "", "", "", "", "", 718 chromeos::DEVICE_TYPE_UNKNOWN, 0, false, false, true, false, false); 719 volume_manager()->OnDiskEvent( 720 chromeos::disks::DiskMountManager::DISK_ADDED, &kMediaDisk); 721 secondary.volume_manager()->OnDiskEvent( 722 chromeos::disks::DiskMountManager::DISK_ADDED, &kMediaDisk); 723 724 // The profile with external storage enabled should have mounted the volume. 725 bool has_volume_mounted = false; 726 for (size_t i = 0; i < main_observer.events().size(); ++i) { 727 if (main_observer.events()[i].type == 728 LoggingObserver::Event::VOLUME_MOUNTED) 729 has_volume_mounted = true; 730 } 731 EXPECT_TRUE(has_volume_mounted); 732 733 // The other profiles with external storage disabled should have not. 734 has_volume_mounted = false; 735 for (size_t i = 0; i < secondary_observer.events().size(); ++i) { 736 if (secondary_observer.events()[i].type == 737 LoggingObserver::Event::VOLUME_MOUNTED) 738 has_volume_mounted = true; 739 } 740 EXPECT_FALSE(has_volume_mounted); 741 742 volume_manager()->RemoveObserver(&main_observer); 743 secondary.volume_manager()->RemoveObserver(&secondary_observer); 744 } 745 746 TEST_F(VolumeManagerTest, GetVolumeInfoList) { 747 volume_manager()->Initialize(); // Adds "Downloads" 748 std::vector<VolumeInfo> info_list = volume_manager()->GetVolumeInfoList(); 749 ASSERT_EQ(1u, info_list.size()); 750 EXPECT_EQ("downloads:Downloads", info_list[0].volume_id); 751 EXPECT_EQ(VOLUME_TYPE_DOWNLOADS_DIRECTORY, info_list[0].type); 752 } 753 754 TEST_F(VolumeManagerTest, FindVolumeInfoById) { 755 volume_manager()->Initialize(); // Adds "Downloads" 756 VolumeInfo volume_info; 757 ASSERT_FALSE(volume_manager()->FindVolumeInfoById( 758 "nonexistent", &volume_info)); 759 ASSERT_TRUE(volume_manager()->FindVolumeInfoById( 760 "downloads:Downloads", &volume_info)); 761 EXPECT_EQ("downloads:Downloads", volume_info.volume_id); 762 EXPECT_EQ(VOLUME_TYPE_DOWNLOADS_DIRECTORY, volume_info.type); 763 } 764 765 TEST_F(VolumeManagerTest, ArchiveSourceFiltering) { 766 LoggingObserver observer; 767 volume_manager()->AddObserver(&observer); 768 769 // Mount a USB stick. 770 volume_manager()->OnMountEvent( 771 chromeos::disks::DiskMountManager::MOUNTING, 772 chromeos::MOUNT_ERROR_NONE, 773 chromeos::disks::DiskMountManager::MountPointInfo( 774 "/removable/usb", 775 "/removable/usb", 776 chromeos::MOUNT_TYPE_DEVICE, 777 chromeos::disks::MOUNT_CONDITION_NONE)); 778 779 // Mount a zip archive in the stick. 780 volume_manager()->OnMountEvent( 781 chromeos::disks::DiskMountManager::MOUNTING, 782 chromeos::MOUNT_ERROR_NONE, 783 chromeos::disks::DiskMountManager::MountPointInfo( 784 "/removable/usb/1.zip", 785 "/archive/1", 786 chromeos::MOUNT_TYPE_ARCHIVE, 787 chromeos::disks::MOUNT_CONDITION_NONE)); 788 VolumeInfo volume_info; 789 ASSERT_TRUE(volume_manager()->FindVolumeInfoById("archive:1", &volume_info)); 790 EXPECT_EQ("/archive/1", volume_info.mount_path.AsUTF8Unsafe()); 791 EXPECT_EQ(2u, observer.events().size()); 792 793 // Mount a zip archive in the previous zip archive. 794 volume_manager()->OnMountEvent( 795 chromeos::disks::DiskMountManager::MOUNTING, 796 chromeos::MOUNT_ERROR_NONE, 797 chromeos::disks::DiskMountManager::MountPointInfo( 798 "/archive/1/2.zip", 799 "/archive/2", 800 chromeos::MOUNT_TYPE_ARCHIVE, 801 chromeos::disks::MOUNT_CONDITION_NONE)); 802 ASSERT_TRUE(volume_manager()->FindVolumeInfoById("archive:2", &volume_info)); 803 EXPECT_EQ("/archive/2", volume_info.mount_path.AsUTF8Unsafe()); 804 EXPECT_EQ(3u, observer.events().size()); 805 806 // A zip file is mounted from other profile. It must be ignored in the current 807 // VolumeManager. 808 volume_manager()->OnMountEvent( 809 chromeos::disks::DiskMountManager::MOUNTING, 810 chromeos::MOUNT_ERROR_NONE, 811 chromeos::disks::DiskMountManager::MountPointInfo( 812 "/other/profile/drive/folder/3.zip", 813 "/archive/3", 814 chromeos::MOUNT_TYPE_ARCHIVE, 815 chromeos::disks::MOUNT_CONDITION_NONE)); 816 EXPECT_FALSE(volume_manager()->FindVolumeInfoById("archive:3", &volume_info)); 817 EXPECT_EQ(3u, observer.events().size()); 818 } 819 820 TEST_F(VolumeManagerTest, HardUnplugged) { 821 LoggingObserver observer; 822 volume_manager()->AddObserver(&observer); 823 volume_manager()->OnDeviceEvent( 824 chromeos::disks::DiskMountManager::DEVICE_REMOVED, "device1"); 825 826 // Disk that has a mount path is removed. 827 chromeos::disks::DiskMountManager::Disk disk("device1", 828 "/mount/path", 829 "", 830 "", 831 "", 832 "", 833 "", 834 "", 835 "", 836 "", 837 "uuid1", 838 "device1", 839 chromeos::DEVICE_TYPE_UNKNOWN, 840 0, 841 false, 842 false, 843 false, 844 false, 845 false); 846 disk_mount_manager_->InvokeDiskEventForTest( 847 chromeos::disks::DiskMountManager::DISK_REMOVED, &disk); 848 849 volume_manager()->OnDeviceEvent( 850 chromeos::disks::DiskMountManager::DEVICE_REMOVED, "device1"); 851 852 EXPECT_EQ(2u, observer.events().size()); 853 EXPECT_EQ(LoggingObserver::Event::DEVICE_REMOVED, observer.events()[0].type); 854 EXPECT_EQ(LoggingObserver::Event::DEVICE_REMOVED, observer.events()[1].type); 855 EXPECT_FALSE(observer.events()[0].hard_unplugged); 856 EXPECT_TRUE(observer.events()[1].hard_unplugged); 857 } 858 859 TEST_F(VolumeManagerTest, MTPPlugAndUnplug) { 860 LoggingObserver observer; 861 volume_manager()->AddObserver(&observer); 862 863 storage_monitor::StorageInfo info( 864 storage_monitor::StorageInfo::MakeDeviceId( 865 storage_monitor::StorageInfo::MTP_OR_PTP, "dummy-device-id"), 866 FILE_PATH_LITERAL("/dummy/device/location"), 867 base::UTF8ToUTF16("label"), 868 base::UTF8ToUTF16("vendor"), 869 base::UTF8ToUTF16("model"), 870 12345 /* size */); 871 872 storage_monitor::StorageInfo non_mtp_info( 873 storage_monitor::StorageInfo::MakeDeviceId( 874 storage_monitor::StorageInfo::IPHOTO, "dummy-device-id2"), 875 FILE_PATH_LITERAL("/dummy/device/location2"), 876 base::UTF8ToUTF16("label2"), 877 base::UTF8ToUTF16("vendor2"), 878 base::UTF8ToUTF16("model2"), 879 12345 /* size */); 880 881 // Attach 882 volume_manager()->OnRemovableStorageAttached(info); 883 ASSERT_EQ(1u, observer.events().size()); 884 EXPECT_EQ(LoggingObserver::Event::VOLUME_MOUNTED, observer.events()[0].type); 885 886 VolumeInfo volume_info; 887 ASSERT_TRUE(volume_manager()->FindVolumeInfoById("mtp:model", &volume_info)); 888 EXPECT_EQ(VOLUME_TYPE_MTP, volume_info.type); 889 890 // Non MTP events from storage monitor are ignored. 891 volume_manager()->OnRemovableStorageAttached(non_mtp_info); 892 EXPECT_EQ(1u, observer.events().size()); 893 894 // Detach 895 volume_manager()->OnRemovableStorageDetached(info); 896 ASSERT_EQ(2u, observer.events().size()); 897 EXPECT_EQ(LoggingObserver::Event::VOLUME_UNMOUNTED, 898 observer.events()[1].type); 899 900 EXPECT_FALSE(volume_manager()->FindVolumeInfoById("mtp:model", &volume_info)); 901 } 902 903 } // namespace file_manager 904