// Copyright 2014 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "apps/saved_devices_service.h" #include "base/run_loop.h" #include "base/strings/utf_string_conversions.h" #include "base/test/values_test_util.h" #include "chrome/browser/extensions/test_extension_environment.h" #include "chrome/test/base/testing_profile.h" #include "device/usb/usb_device.h" #include "device/usb/usb_device_handle.h" #include "extensions/browser/extension_prefs.h" #include "extensions/common/extension.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" namespace apps { namespace { using device::UsbDevice; using device::UsbDeviceHandle; using device::UsbEndpointDirection; using device::UsbTransferCallback; using testing::Return; class MockUsbDevice : public UsbDevice { public: MockUsbDevice(const std::string& serial_number, uint32 unique_id) : UsbDevice(0, 0, unique_id), serial_number_(serial_number) {} MOCK_METHOD0(Open, scoped_refptr()); MOCK_METHOD1(Close, bool(scoped_refptr)); #if defined(OS_CHROMEOS) MOCK_METHOD2(RequestUsbAccess, void(int, const base::Callback&)); #endif MOCK_METHOD0(GetConfiguration, const device::UsbConfigDescriptor&()); MOCK_METHOD1(GetManufacturer, bool(base::string16*)); MOCK_METHOD1(GetProduct, bool(base::string16*)); bool GetSerialNumber(base::string16* serial) OVERRIDE { if (serial_number_.empty()) { return false; } *serial = base::UTF8ToUTF16(serial_number_); return true; } void NotifyDisconnect() { UsbDevice::NotifyDisconnect(); } private: virtual ~MockUsbDevice() {} const std::string serial_number_; }; } class SavedDevicesServiceTest : public testing::Test { protected: virtual void SetUp() OVERRIDE { testing::Test::SetUp(); env_.GetExtensionPrefs(); // Force creation before adding extensions. extension_ = env_.MakeExtension(*base::test::ParseJson( "{" " \"app\": {" " \"background\": {" " \"scripts\": [\"background.js\"]" " }" " }," " \"permissions\": [" " \"usb\"" " ]" "}")); service_ = SavedDevicesService::Get(env_.profile()); device0 = new MockUsbDevice("ABCDE", 0); device1 = new MockUsbDevice("", 1); device2 = new MockUsbDevice("12345", 2); device3 = new MockUsbDevice("", 3); } extensions::TestExtensionEnvironment env_; const extensions::Extension* extension_; SavedDevicesService* service_; scoped_refptr device0; scoped_refptr device1; scoped_refptr device2; scoped_refptr device3; }; TEST_F(SavedDevicesServiceTest, RegisterDevices) { SavedDevicesService::SavedDevices* saved_devices = service_->GetOrInsert(extension_->id()); base::string16 serial_number(base::ASCIIToUTF16("ABCDE")); saved_devices->RegisterDevice(device0, &serial_number); saved_devices->RegisterDevice(device1, NULL); // This is necessary as writing out registered devices happens in a task on // the UI thread. base::RunLoop run_loop; run_loop.RunUntilIdle(); ASSERT_TRUE(saved_devices->IsRegistered(device0)); ASSERT_TRUE(saved_devices->IsRegistered(device1)); ASSERT_FALSE(saved_devices->IsRegistered(device2)); ASSERT_FALSE(saved_devices->IsRegistered(device3)); std::vector device_entries = service_->GetAllDevices(extension_->id()); ASSERT_EQ(1U, device_entries.size()); ASSERT_EQ(base::ASCIIToUTF16("ABCDE"), device_entries[0].serial_number); device1->NotifyDisconnect(); ASSERT_TRUE(saved_devices->IsRegistered(device0)); ASSERT_FALSE(saved_devices->IsRegistered(device1)); ASSERT_FALSE(saved_devices->IsRegistered(device2)); ASSERT_FALSE(saved_devices->IsRegistered(device3)); service_->Clear(extension_->id()); // App is normally restarted, clearing its reference to the SavedDevices. saved_devices = service_->GetOrInsert(extension_->id()); ASSERT_FALSE(saved_devices->IsRegistered(device0)); device_entries = service_->GetAllDevices(extension_->id()); ASSERT_EQ(0U, device_entries.size()); } TEST_F(SavedDevicesServiceTest, LoadPrefs) { scoped_ptr prefs_value = base::test::ParseJson( "[" " {" " \"product_id\": 0," " \"serial_number\": \"ABCDE\"," " \"type\": \"usb\"," " \"vendor_id\": 0" " }" "]"); env_.GetExtensionPrefs()->UpdateExtensionPref( extension_->id(), "devices", prefs_value.release()); SavedDevicesService::SavedDevices* saved_devices = service_->GetOrInsert(extension_->id()); ASSERT_TRUE(saved_devices->IsRegistered(device0)); ASSERT_FALSE(saved_devices->IsRegistered(device1)); ASSERT_FALSE(saved_devices->IsRegistered(device2)); ASSERT_FALSE(saved_devices->IsRegistered(device3)); } } // namespace apps