103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)// found in the LICENSE file.
403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "chrome/browser/chromeos/extensions/file_manager/device_event_router.h"
603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include <string>
803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include <vector>
903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
1003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "base/message_loop/message_loop.h"
1103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "base/run_loop.h"
1203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "chrome/browser/chromeos/file_manager/volume_manager.h"
1303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
1403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
1503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)namespace file_manager {
1603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)namespace {
1703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccinamespace file_manager_private = extensions::api::file_manager_private;
1903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)typedef chromeos::disks::DiskMountManager::Disk Disk;
2003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
2103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)const char kTestDevicePath[] = "/device/test";
2203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
2303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)struct DeviceEvent {
241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  extensions::api::file_manager_private::DeviceEventType type;
2503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  std::string device_path;
2603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)};
2703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
2803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)// DeviceEventRouter implementation for testing.
2903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)class DeviceEventRouterImpl : public DeviceEventRouter {
3003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) public:
3103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  DeviceEventRouterImpl()
3203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      : DeviceEventRouter(base::TimeDelta::FromSeconds(0)),
3303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        external_storage_disabled(false) {}
3403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  virtual ~DeviceEventRouterImpl() {}
3503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
3603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // DeviceEventRouter overrides.
371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  virtual void OnDeviceEvent(file_manager_private::DeviceEventType type,
3803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                             const std::string& device_path) OVERRIDE {
3903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    DeviceEvent event;
4003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    event.type = type;
4103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    event.device_path = device_path;
4203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    events.push_back(event);
4303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  }
4403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
4503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // DeviceEventRouter overrides.
4603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  virtual bool IsExternalStorageDisabled() OVERRIDE {
4703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    return external_storage_disabled;
4803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  }
4903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
5003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // List of dispatched events.
5103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  std::vector<DeviceEvent> events;
5203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
5303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // Flag returned by |IsExternalStorageDisabled|.
5403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  bool external_storage_disabled;
5503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
5603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) private:
5703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(DeviceEventRouterImpl);
5803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)};
5903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
6003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)}  // namespace
6103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
6203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)class DeviceEventRouterTest : public testing::Test {
6303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) protected:
6403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  virtual void SetUp() OVERRIDE {
6503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    device_event_router.reset(new DeviceEventRouterImpl());
6603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  }
6703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
6803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // Creates a disk instance with |device_path| and |mount_path| for testing.
6903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  Disk CreateTestDisk(const std::string& device_path,
7003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                      const std::string& mount_path) {
7103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    return Disk(device_path,
7203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                mount_path,
7303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                "",
7403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                "",
7503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                "",
7603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                "",
7703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                "",
7803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                "",
7903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                "",
8003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                "",
8103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                "",
8203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                device_path,
8303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                chromeos::DEVICE_TYPE_UNKNOWN,
8403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                0,
8503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                false,
8603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                false,
8703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                false,
8803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                false,
8903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                false,
9003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                false);
9103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  }
9203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
9303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // Creates a volume info instance with |device_path| and |mount_path| for
9403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // testing.
9503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  VolumeInfo CreateTestVolumeInfo(const std::string& device_path,
9603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                                  const std::string& mount_path) {
9703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    VolumeInfo volume_info;
9803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    volume_info.system_path_prefix = base::FilePath(device_path);
9903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    volume_info.mount_path = base::FilePath(mount_path);
10003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    return volume_info;
10103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  }
10203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
10303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  scoped_ptr<DeviceEventRouterImpl> device_event_router;
10403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
10503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) private:
10603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  base::MessageLoop message_loop_;
10703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)};
10803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
10903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)TEST_F(DeviceEventRouterTest, AddAndRemoveDevice) {
11003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  const Disk disk1 = CreateTestDisk("/device/test", "/mount/path1");
11103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  const Disk disk1_unmounted = CreateTestDisk("/device/test", "");
11203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  const VolumeInfo volumeInfo =
11303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      CreateTestVolumeInfo("/device/test", "/mount/path1");
11403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  device_event_router->OnDeviceAdded("/device/test");
11503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  device_event_router->OnDiskAdded(disk1, true);
1161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  device_event_router->OnVolumeMounted(chromeos::MOUNT_ERROR_NONE, volumeInfo);
11703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  device_event_router->OnVolumeUnmounted(chromeos::MOUNT_ERROR_NONE,
11803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                                         volumeInfo);
11903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  device_event_router->OnDiskRemoved(disk1_unmounted);
12003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  device_event_router->OnDeviceRemoved("/device/test");
12103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  ASSERT_EQ(1u, device_event_router->events.size());
1221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(file_manager_private::DEVICE_EVENT_TYPE_REMOVED,
12303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)            device_event_router->events[0].type);
12403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  EXPECT_EQ("/device/test", device_event_router->events[0].device_path);
12503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)}
12603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
12703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)TEST_F(DeviceEventRouterTest, HardUnplugged) {
12803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  const Disk disk1 = CreateTestDisk("/device/test", "/mount/path1");
12903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  const Disk disk2 = CreateTestDisk("/device/test", "/mount/path2");
13003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  device_event_router->OnDeviceAdded("/device/test");
13103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  device_event_router->OnDiskAdded(disk1, true);
13203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  device_event_router->OnDiskAdded(disk2, true);
13303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  device_event_router->OnDiskRemoved(disk1);
13403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  device_event_router->OnDiskRemoved(disk2);
13503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  device_event_router->OnDeviceRemoved(kTestDevicePath);
13603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  base::RunLoop().RunUntilIdle();
13703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  ASSERT_EQ(2u, device_event_router->events.size());
1381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(file_manager_private::DEVICE_EVENT_TYPE_HARD_UNPLUGGED,
13903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)            device_event_router->events[0].type);
14003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  EXPECT_EQ("/device/test", device_event_router->events[0].device_path);
1411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(file_manager_private::DEVICE_EVENT_TYPE_REMOVED,
14203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)            device_event_router->events[1].type);
14303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  EXPECT_EQ("/device/test", device_event_router->events[1].device_path);
14403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)}
14503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
14603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)}  // namespace file_manager
147