diff options
author | ygorshenin@chromium.org <ygorshenin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-04-17 13:03:52 +0000 |
---|---|---|
committer | ygorshenin@chromium.org <ygorshenin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-04-17 13:03:52 +0000 |
commit | 2ec4cd9da32b9cd341d31c7dfab81fa0d694cf25 (patch) | |
tree | 062d0e395d218faa412c5d3ce36e4f146d1f7c21 | |
parent | caad7bd9397b8eb75e8eea9ecc58874d86d9a874 (diff) | |
download | chromium_src-2ec4cd9da32b9cd341d31c7dfab81fa0d694cf25.zip chromium_src-2ec4cd9da32b9cd341d31c7dfab81fa0d694cf25.tar.gz chromium_src-2ec4cd9da32b9cd341d31c7dfab81fa0d694cf25.tar.bz2 |
Added InputServiceProxy, which lives on the UI thread and forwards all calls to the InputServiceLinux.
BUG=357050
TEST=browser_tests:InputServiceProxy*
Review URL: https://codereview.chromium.org/232773015
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@264495 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/browser/chromeos/device/DEPS | 3 | ||||
-rw-r--r-- | chrome/browser/chromeos/device/input_service_proxy.cc | 148 | ||||
-rw-r--r-- | chrome/browser/chromeos/device/input_service_proxy.h | 65 | ||||
-rw-r--r-- | chrome/browser/chromeos/device/input_service_proxy_browsertest.cc | 203 | ||||
-rw-r--r-- | chrome/chrome_browser_chromeos.gypi | 3 | ||||
-rw-r--r-- | chrome/chrome_tests.gypi | 1 | ||||
-rw-r--r-- | device/hid/input_service_linux.cc | 154 | ||||
-rw-r--r-- | device/hid/input_service_linux.h | 15 |
8 files changed, 529 insertions, 63 deletions
diff --git a/chrome/browser/chromeos/device/DEPS b/chrome/browser/chromeos/device/DEPS new file mode 100644 index 0000000..2225efa --- /dev/null +++ b/chrome/browser/chromeos/device/DEPS @@ -0,0 +1,3 @@ +include_rules = [ + "+device/hid" +] diff --git a/chrome/browser/chromeos/device/input_service_proxy.cc b/chrome/browser/chromeos/device/input_service_proxy.cc new file mode 100644 index 0000000..f065775 --- /dev/null +++ b/chrome/browser/chromeos/device/input_service_proxy.cc @@ -0,0 +1,148 @@ +// 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 "chrome/browser/chromeos/device/input_service_proxy.h" + +#include "base/task_runner_util.h" +#include "content/public/browser/browser_thread.h" + +using content::BrowserThread; +using device::InputServiceLinux; + +typedef device::InputServiceLinux::InputDeviceInfo InputDeviceInfo; + +namespace chromeos { + +class InputServiceProxy::ServiceObserver : public InputServiceLinux::Observer { + public: + ServiceObserver() { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); } + virtual ~ServiceObserver() { DCHECK(CalledOnValidThread()); } + + void Initialize(const base::WeakPtr<InputServiceProxy>& proxy) { + DCHECK(CalledOnValidThread()); + InputServiceLinux::GetInstance()->AddObserver(this); + proxy_ = proxy; + } + + void Shutdown() { + DCHECK(CalledOnValidThread()); + if (InputServiceLinux::HasInstance()) + InputServiceLinux::GetInstance()->RemoveObserver(this); + delete this; + } + + std::vector<InputDeviceInfo> GetDevices() { + DCHECK(CalledOnValidThread()); + std::vector<InputDeviceInfo> devices; + if (InputServiceLinux::HasInstance()) + InputServiceLinux::GetInstance()->GetDevices(&devices); + return devices; + } + + void GetDeviceInfo(const std::string& id, + const InputServiceProxy::GetDeviceInfoCallback& callback) { + DCHECK(CalledOnValidThread()); + bool success = false; + InputDeviceInfo info; + info.id = id; + if (InputServiceLinux::HasInstance()) + success = InputServiceLinux::GetInstance()->GetDeviceInfo(id, &info); + BrowserThread::PostTask( + BrowserThread::UI, FROM_HERE, base::Bind(callback, success, info)); + } + + // InputServiceLinux::Observer implementation: + virtual void OnInputDeviceAdded( + const InputServiceLinux::InputDeviceInfo& info) OVERRIDE { + DCHECK(CalledOnValidThread()); + BrowserThread::PostTask( + BrowserThread::UI, + FROM_HERE, + base::Bind(&InputServiceProxy::OnDeviceAdded, proxy_, info)); + } + + virtual void OnInputDeviceRemoved(const std::string& id) OVERRIDE { + DCHECK(CalledOnValidThread()); + BrowserThread::PostTask( + BrowserThread::UI, + FROM_HERE, + base::Bind(&InputServiceProxy::OnDeviceRemoved, proxy_, id)); + } + + private: + bool CalledOnValidThread() const { + return BrowserThread::CurrentlyOn(BrowserThread::FILE); + } + + base::WeakPtr<InputServiceProxy> proxy_; + + DISALLOW_COPY_AND_ASSIGN(ServiceObserver); +}; + +InputServiceProxy::InputServiceProxy() + : service_observer_(new ServiceObserver()), weak_factory_(this) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + BrowserThread::PostTask( + BrowserThread::FILE, + FROM_HERE, + base::Bind(&InputServiceProxy::ServiceObserver::Initialize, + base::Unretained(service_observer_.get()), + weak_factory_.GetWeakPtr())); +} + +InputServiceProxy::~InputServiceProxy() { + DCHECK(thread_checker_.CalledOnValidThread()); + BrowserThread::PostTask( + BrowserThread::FILE, + FROM_HERE, + base::Bind(&InputServiceProxy::ServiceObserver::Shutdown, + base::Unretained(service_observer_.release()))); +} + +void InputServiceProxy::AddObserver(Observer* observer) { + DCHECK(thread_checker_.CalledOnValidThread()); + if (observer) + observers_.AddObserver(observer); +} + +void InputServiceProxy::RemoveObserver(Observer* observer) { + DCHECK(thread_checker_.CalledOnValidThread()); + if (observer) + observers_.RemoveObserver(observer); +} + +void InputServiceProxy::GetDevices(const GetDevicesCallback& callback) { + DCHECK(thread_checker_.CalledOnValidThread()); + BrowserThread::PostTaskAndReplyWithResult( + BrowserThread::FILE, + FROM_HERE, + base::Bind(&InputServiceProxy::ServiceObserver::GetDevices, + base::Unretained(service_observer_.get())), + callback); +} + +void InputServiceProxy::GetDeviceInfo(const std::string& id, + const GetDeviceInfoCallback& callback) { + DCHECK(thread_checker_.CalledOnValidThread()); + BrowserThread::PostTask( + BrowserThread::FILE, + FROM_HERE, + base::Bind(&InputServiceProxy::ServiceObserver::GetDeviceInfo, + base::Unretained(service_observer_.release()), + id, + callback)); +} + +void InputServiceProxy::OnDeviceAdded( + const InputServiceLinux::InputDeviceInfo& info) { + DCHECK(thread_checker_.CalledOnValidThread()); + FOR_EACH_OBSERVER(Observer, observers_, OnInputDeviceAdded(info)); +} + +void InputServiceProxy::OnDeviceRemoved(const std::string& id) { + DCHECK(thread_checker_.CalledOnValidThread()); + FOR_EACH_OBSERVER(Observer, observers_, OnInputDeviceRemoved(id)); +} + +} // namespace chromeos diff --git a/chrome/browser/chromeos/device/input_service_proxy.h b/chrome/browser/chromeos/device/input_service_proxy.h new file mode 100644 index 0000000..11ba071 --- /dev/null +++ b/chrome/browser/chromeos/device/input_service_proxy.h @@ -0,0 +1,65 @@ +// 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. + +#ifndef CHROME_BROWSER_CHROMEOS_DEVICE_INPUT_SERVICE_PROXY_H_ +#define CHROME_BROWSER_CHROMEOS_DEVICE_INPUT_SERVICE_PROXY_H_ + +#include <vector> + +#include "base/callback.h" +#include "base/memory/scoped_ptr.h" +#include "base/memory/weak_ptr.h" +#include "base/observer_list.h" +#include "base/threading/thread_checker.h" +#include "device/hid/input_service_linux.h" + +namespace chromeos { + +// Proxy to device::InputServiceLinux. Should be created and used on the UI +// thread. +class InputServiceProxy { + public: + typedef device::InputServiceLinux::InputDeviceInfo InputDeviceInfo; + + class Observer { + public: + virtual ~Observer() {} + virtual void OnInputDeviceAdded(const InputDeviceInfo& info) = 0; + virtual void OnInputDeviceRemoved(const std::string& id) = 0; + }; + + typedef base::Callback<void(const std::vector<InputDeviceInfo>& devices)> + GetDevicesCallback; + typedef base::Callback<void(bool success, const InputDeviceInfo& info)> + GetDeviceInfoCallback; + + InputServiceProxy(); + ~InputServiceProxy(); + + void AddObserver(Observer* observer); + void RemoveObserver(Observer* observer); + + void GetDevices(const GetDevicesCallback& callback); + void GetDeviceInfo(const std::string& id, + const GetDeviceInfoCallback& callback); + + private: + class ServiceObserver; + + void OnDeviceAdded(const device::InputServiceLinux::InputDeviceInfo& info); + void OnDeviceRemoved(const std::string& id); + + ObserverList<Observer> observers_; + scoped_ptr<ServiceObserver> service_observer_; + + base::ThreadChecker thread_checker_; + + base::WeakPtrFactory<InputServiceProxy> weak_factory_; + + DISALLOW_COPY_AND_ASSIGN(InputServiceProxy); +}; + +} // namespace chromeos + +#endif // CHROME_BROWSER_CHROMEOS_DEVICE_INPUT_SERVICE_PROXY_H_ diff --git a/chrome/browser/chromeos/device/input_service_proxy_browsertest.cc b/chrome/browser/chromeos/device/input_service_proxy_browsertest.cc new file mode 100644 index 0000000..be7e8ce --- /dev/null +++ b/chrome/browser/chromeos/device/input_service_proxy_browsertest.cc @@ -0,0 +1,203 @@ +// 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 "base/bind.h" +#include "base/compiler_specific.h" +#include "base/macros.h" +#include "base/run_loop.h" +#include "chrome/browser/chromeos/device/input_service_proxy.h" +#include "chrome/test/base/in_process_browser_test.h" +#include "content/public/browser/browser_thread.h" +#include "device/hid/input_service_linux.h" + +using content::BrowserThread; +using device::InputServiceLinux; + +typedef InputServiceLinux::InputDeviceInfo InputDeviceInfo; + +namespace chromeos { + +namespace { + +const char kKeyboardId[] = "keyboard"; +const char kMouseId[] = "mouse"; + +class InputServiceLinuxTestImpl : public InputServiceLinux { + public: + InputServiceLinuxTestImpl() {} + virtual ~InputServiceLinuxTestImpl() {} + + void AddDeviceForTesting(const InputDeviceInfo& info) { AddDevice(info); } + void RemoveDeviceForTesting(const std::string& id) { RemoveDevice(id); } + + private: + DISALLOW_COPY_AND_ASSIGN(InputServiceLinuxTestImpl); +}; + +class TestObserver : public InputServiceProxy::Observer { + public: + TestObserver() + : wait_for_device_addition_(false), wait_for_device_removal_(false) {} + virtual ~TestObserver() {} + + virtual void OnInputDeviceAdded(const InputDeviceInfo& info) OVERRIDE { + if (!wait_for_device_addition_) + return; + EXPECT_TRUE(Equals(expected_info_, info)); + done_.Run(); + } + + virtual void OnInputDeviceRemoved(const std::string& id) OVERRIDE { + if (!wait_for_device_removal_) + return; + EXPECT_EQ(expected_id_, id); + done_.Run(); + } + + void WaitForDeviceAddition(const InputDeviceInfo& info) { + base::RunLoop run; + expected_info_ = info; + wait_for_device_addition_ = true; + done_ = run.QuitClosure(); + + run.Run(); + + done_.Reset(); + wait_for_device_addition_ = false; + } + + void WaitForDeviceRemoval(const std::string& id) { + base::RunLoop run; + expected_id_ = id; + wait_for_device_removal_ = true; + done_ = run.QuitClosure(); + + run.Run(); + + done_.Reset(); + wait_for_device_removal_ = false; + } + + private: + static bool Equals(const InputDeviceInfo& lhs, const InputDeviceInfo& rhs) { + return lhs.id == rhs.id && lhs.name == rhs.name && + lhs.subsystem == rhs.subsystem && + lhs.is_accelerometer == rhs.is_accelerometer && + lhs.is_joystick == rhs.is_joystick && lhs.is_key == rhs.is_key && + lhs.is_keyboard == rhs.is_keyboard && lhs.is_mouse == rhs.is_mouse && + lhs.is_tablet == rhs.is_tablet && + lhs.is_touchpad == rhs.is_touchpad && + lhs.is_touchscreen == rhs.is_touchscreen; + } + + InputDeviceInfo expected_info_; + std::string expected_id_; + + bool wait_for_device_addition_; + bool wait_for_device_removal_; + + base::Closure done_; + + DISALLOW_COPY_AND_ASSIGN(TestObserver); +}; + +void InitInputService() { + InputServiceLinux::SetForTesting(new InputServiceLinuxTestImpl()); +} + +void AddDevice(const InputDeviceInfo& device) { + InputServiceLinuxTestImpl* service = + static_cast<InputServiceLinuxTestImpl*>(InputServiceLinux::GetInstance()); + service->AddDeviceForTesting(device); +} + +void RemoveDevice(const std::string& id) { + InputServiceLinuxTestImpl* service = + static_cast<InputServiceLinuxTestImpl*>(InputServiceLinux::GetInstance()); + service->RemoveDeviceForTesting(id); +} + +void OnGetDevices(const base::Closure& done, + const std::vector<InputDeviceInfo>& devices) { + EXPECT_EQ(2, static_cast<int>(devices.size())); + done.Run(); +} + +void OnGetKeyboard(const base::Closure& done, + bool success, + const InputDeviceInfo& info) { + EXPECT_TRUE(success); + EXPECT_EQ("keyboard", info.id); + EXPECT_TRUE(info.is_keyboard); + done.Run(); +} + +void OnGetMouse(const base::Closure& done, + bool success, + const InputDeviceInfo& /* info */) { + EXPECT_FALSE(success); + done.Run(); +} + +} // namespace + +class InputServiceProxyTest : public InProcessBrowserTest { + public: + InputServiceProxyTest() {} + virtual ~InputServiceProxyTest() {} + + private: + DISALLOW_COPY_AND_ASSIGN(InputServiceProxyTest); +}; + +IN_PROC_BROWSER_TEST_F(InputServiceProxyTest, Simple) { + BrowserThread::PostTask( + BrowserThread::FILE, FROM_HERE, base::Bind(&InitInputService)); + InputServiceProxy proxy; + TestObserver observer; + proxy.AddObserver(&observer); + + InputDeviceInfo keyboard; + keyboard.id = kKeyboardId; + keyboard.subsystem = InputServiceLinux::InputDeviceInfo::SUBSYSTEM_INPUT; + keyboard.is_keyboard = true; + BrowserThread::PostTask( + BrowserThread::FILE, FROM_HERE, base::Bind(&AddDevice, keyboard)); + observer.WaitForDeviceAddition(keyboard); + + InputDeviceInfo mouse; + mouse.id = kMouseId; + mouse.subsystem = InputServiceLinux::InputDeviceInfo::SUBSYSTEM_INPUT; + mouse.is_mouse = true; + BrowserThread::PostTask( + BrowserThread::FILE, FROM_HERE, base::Bind(&AddDevice, mouse)); + observer.WaitForDeviceAddition(mouse); + + { + base::RunLoop run; + proxy.GetDevices(base::Bind(&OnGetDevices, run.QuitClosure())); + run.Run(); + } + + BrowserThread::PostTask( + BrowserThread::FILE, FROM_HERE, base::Bind(&RemoveDevice, kMouseId)); + observer.WaitForDeviceRemoval(kMouseId); + + { + base::RunLoop run; + proxy.GetDeviceInfo(kKeyboardId, + base::Bind(&OnGetKeyboard, run.QuitClosure())); + run.Run(); + } + + { + base::RunLoop run; + proxy.GetDeviceInfo(kMouseId, base::Bind(&OnGetMouse, run.QuitClosure())); + run.Run(); + } + + proxy.RemoveObserver(&observer); +} + +} // namespace chromeos diff --git a/chrome/chrome_browser_chromeos.gypi b/chrome/chrome_browser_chromeos.gypi index 1236ce9..1fbb85f 100644 --- a/chrome/chrome_browser_chromeos.gypi +++ b/chrome/chrome_browser_chromeos.gypi @@ -62,6 +62,7 @@ '../crypto/crypto.gyp:crypto', '../dbus/dbus.gyp:dbus', '../device/bluetooth/bluetooth.gyp:device_bluetooth', + '../device/hid/hid.gyp:device_hid', '../media/media.gyp:media', '../net/net.gyp:net', '../ppapi/ppapi_internal.gyp:ppapi_ipc', # For PpapiMsg_LoadPlugin @@ -200,6 +201,8 @@ 'browser/chromeos/dbus/proxy_resolution_service_provider.h', 'browser/chromeos/dbus/screen_lock_service_provider.cc', 'browser/chromeos/dbus/screen_lock_service_provider.h', + 'browser/chromeos/device/input_service_proxy.cc', + 'browser/chromeos/device/input_service_proxy.h', 'browser/chromeos/device_hierarchy_observer.h', 'browser/chromeos/device_uma.cc', 'browser/chromeos/device_uma.h', diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi index 85e0914..6b4cbd5 100644 --- a/chrome/chrome_tests.gypi +++ b/chrome/chrome_tests.gypi @@ -879,6 +879,7 @@ 'browser/chromeos/app_mode/kiosk_app_manager_browsertest.cc', 'browser/chromeos/app_mode/kiosk_app_update_service_browsertest.cc', 'browser/chromeos/attestation/attestation_policy_browsertest.cc', + 'browser/chromeos/device/input_service_proxy_browsertest.cc', 'browser/chromeos/drive/drive_integration_service_browsertest.cc', 'browser/chromeos/drive/drive_notification_manager_factory_browsertest.cc', 'browser/chromeos/drive/test_util.cc', diff --git a/device/hid/input_service_linux.cc b/device/hid/input_service_linux.cc index 7552824..09ecaaf 100644 --- a/device/hid/input_service_linux.cc +++ b/device/hid/input_service_linux.cc @@ -44,6 +44,80 @@ bool GetBoolProperty(udev_device* device, const char* key) { return (value != 0); } +class InputServiceLinuxImpl : public InputServiceLinux, + public DeviceMonitorLinux::Observer { + public: + // Implements DeviceMonitorLinux::Observer: + virtual void OnDeviceAdded(udev_device* device) OVERRIDE; + virtual void OnDeviceRemoved(udev_device* device) OVERRIDE; + + private: + friend class InputServiceLinux; + + InputServiceLinuxImpl(); + virtual ~InputServiceLinuxImpl(); + + DISALLOW_COPY_AND_ASSIGN(InputServiceLinuxImpl); +}; + +InputServiceLinuxImpl::InputServiceLinuxImpl() { + DeviceMonitorLinux::GetInstance()->AddObserver(this); + DeviceMonitorLinux::GetInstance()->Enumerate(base::Bind( + &InputServiceLinuxImpl::OnDeviceAdded, base::Unretained(this))); +} + +InputServiceLinuxImpl::~InputServiceLinuxImpl() { + if (DeviceMonitorLinux::HasInstance()) + DeviceMonitorLinux::GetInstance()->RemoveObserver(this); +} + +void InputServiceLinuxImpl::OnDeviceAdded(udev_device* device) { + DCHECK(CalledOnValidThread()); + if (!device) + return; + const char* path = udev_device_get_syspath(device); + if (!path) + return; + + InputDeviceInfo info; + info.id = path; + + const char* name = udev_device_get_property_value(device, "NAME"); + if (name) + info.name = name; + + const char* subsystem = udev_device_get_subsystem(device); + if (!subsystem) + return; + else if (strcmp(subsystem, kHidSubsystem) == 0) + info.subsystem = InputServiceLinux::InputDeviceInfo::SUBSYSTEM_HID; + else if (strcmp(subsystem, kInputSubsystem) == 0) + info.subsystem = InputServiceLinux::InputDeviceInfo::SUBSYSTEM_INPUT; + else + return; + + info.is_accelerometer = GetBoolProperty(device, kIdInputAccelerometer); + info.is_joystick = GetBoolProperty(device, kIdInputJoystick); + info.is_key = GetBoolProperty(device, kIdInputKey); + info.is_keyboard = GetBoolProperty(device, kIdInputKeyboard); + info.is_mouse = GetBoolProperty(device, kIdInputMouse); + info.is_tablet = GetBoolProperty(device, kIdInputTablet); + info.is_touchpad = GetBoolProperty(device, kIdInputTouchpad); + info.is_touchscreen = GetBoolProperty(device, kIdInputTouchscreen); + + AddDevice(info); +} + +void InputServiceLinuxImpl::OnDeviceRemoved(udev_device* device) { + DCHECK(CalledOnValidThread()); + if (!device) + return; + const char* path = udev_device_get_syspath(device); + if (!path) + return; + RemoveDevice(path); +} + } // namespace InputServiceLinux::InputDeviceInfo::InputDeviceInfo() @@ -60,9 +134,11 @@ InputServiceLinux::InputDeviceInfo::InputDeviceInfo() InputServiceLinux::InputServiceLinux() { base::ThreadRestrictions::AssertIOAllowed(); base::MessageLoop::current()->AddDestructionObserver(this); - DeviceMonitorLinux::GetInstance()->AddObserver(this); - DeviceMonitorLinux::GetInstance()->Enumerate( - base::Bind(&InputServiceLinux::OnDeviceAdded, base::Unretained(this))); +} + +InputServiceLinux::~InputServiceLinux() { + DCHECK(CalledOnValidThread()); + base::MessageLoop::current()->RemoveDestructionObserver(this); } // static @@ -77,28 +153,34 @@ bool InputServiceLinux::HasInstance() { return g_input_service_linux_ptr.Get().get(); } +// static +void InputServiceLinux::SetForTesting(InputServiceLinux* service) { + g_input_service_linux_ptr.Get().reset(service); +} + void InputServiceLinux::AddObserver(Observer* observer) { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK(CalledOnValidThread()); if (observer) observers_.AddObserver(observer); } void InputServiceLinux::RemoveObserver(Observer* observer) { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK(CalledOnValidThread()); if (observer) observers_.RemoveObserver(observer); } void InputServiceLinux::GetDevices(std::vector<InputDeviceInfo>* devices) { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK(CalledOnValidThread()); for (DeviceMap::iterator it = devices_.begin(), ie = devices_.end(); it != ie; - ++it) + ++it) { devices->push_back(it->second); + } } bool InputServiceLinux::GetDeviceInfo(const std::string& id, InputDeviceInfo* info) const { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK(CalledOnValidThread()); DeviceMap::const_iterator it = devices_.find(id); if (it == devices_.end()) return false; @@ -107,64 +189,22 @@ bool InputServiceLinux::GetDeviceInfo(const std::string& id, } void InputServiceLinux::WillDestroyCurrentMessageLoop() { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK(CalledOnValidThread()); g_input_service_linux_ptr.Get().reset(NULL); } -void InputServiceLinux::OnDeviceAdded(udev_device* device) { - DCHECK(thread_checker_.CalledOnValidThread()); - if (!device) - return; - const char* path = udev_device_get_syspath(device); - if (!path) - return; - - InputDeviceInfo info; - info.id = path; - - const char* name = udev_device_get_property_value(device, "NAME"); - if (name) - info.name = name; - - const char* subsystem = udev_device_get_subsystem(device); - if (!subsystem) - return; - else if (strcmp(subsystem, kHidSubsystem) == 0) - info.subsystem = InputServiceLinux::InputDeviceInfo::SUBSYSTEM_HID; - else if (strcmp(subsystem, kInputSubsystem) == 0) - info.subsystem = InputServiceLinux::InputDeviceInfo::SUBSYSTEM_INPUT; - else - return; - - info.is_accelerometer = GetBoolProperty(device, kIdInputAccelerometer); - info.is_joystick = GetBoolProperty(device, kIdInputJoystick); - info.is_key = GetBoolProperty(device, kIdInputKey); - info.is_keyboard = GetBoolProperty(device, kIdInputKeyboard); - info.is_mouse = GetBoolProperty(device, kIdInputMouse); - info.is_tablet = GetBoolProperty(device, kIdInputTablet); - info.is_touchpad = GetBoolProperty(device, kIdInputTouchpad); - info.is_touchscreen = GetBoolProperty(device, kIdInputTouchscreen); - +void InputServiceLinux::AddDevice(const InputDeviceInfo& info) { devices_[info.id] = info; FOR_EACH_OBSERVER(Observer, observers_, OnInputDeviceAdded(info)); } -void InputServiceLinux::OnDeviceRemoved(udev_device* device) { - DCHECK(thread_checker_.CalledOnValidThread()); - if (!device) - return; - const char* path = udev_device_get_syspath(device); - if (!path) - return; - devices_.erase(path); - FOR_EACH_OBSERVER(Observer, observers_, OnInputDeviceRemoved(path)); +void InputServiceLinux::RemoveDevice(const std::string& id) { + devices_.erase(id); + FOR_EACH_OBSERVER(Observer, observers_, OnInputDeviceRemoved(id)); } -InputServiceLinux::~InputServiceLinux() { - DCHECK(thread_checker_.CalledOnValidThread()); - base::MessageLoop::current()->RemoveDestructionObserver(this); - if (DeviceMonitorLinux::HasInstance()) - DeviceMonitorLinux::GetInstance()->RemoveObserver(this); +bool InputServiceLinux::CalledOnValidThread() const { + return thread_checker_.CalledOnValidThread(); } } // namespace device diff --git a/device/hid/input_service_linux.h b/device/hid/input_service_linux.h index 48584f4..edd957b 100644 --- a/device/hid/input_service_linux.h +++ b/device/hid/input_service_linux.h @@ -22,8 +22,7 @@ namespace device { // This class provides information and notifications about // connected/disconnected input/HID devices. This class is *NOT* // thread-safe and all methods must be called from the FILE thread. -class InputServiceLinux : public base::MessageLoop::DestructionObserver, - public DeviceMonitorLinux::Observer { +class InputServiceLinux : public base::MessageLoop::DestructionObserver { public: struct InputDeviceInfo { enum Subsystem { SUBSYSTEM_HID, SUBSYSTEM_INPUT, SUBSYSTEM_UNKNOWN }; @@ -55,6 +54,7 @@ class InputServiceLinux : public base::MessageLoop::DestructionObserver, static InputServiceLinux* GetInstance(); static bool HasInstance(); + static void SetForTesting(InputServiceLinux* service); void AddObserver(Observer* observer); void RemoveObserver(Observer* observer); @@ -70,15 +70,18 @@ class InputServiceLinux : public base::MessageLoop::DestructionObserver, // Implements base::MessageLoop::DestructionObserver virtual void WillDestroyCurrentMessageLoop() OVERRIDE; - // Implements DeviceMonitorLinux::Observer: - virtual void OnDeviceAdded(udev_device* device) OVERRIDE; - virtual void OnDeviceRemoved(udev_device* device) OVERRIDE; + protected: + virtual ~InputServiceLinux(); + + void AddDevice(const InputDeviceInfo& info); + void RemoveDevice(const std::string& id); + + bool CalledOnValidThread() const; private: friend struct base::DefaultDeleter<InputServiceLinux>; typedef base::hash_map<std::string, InputDeviceInfo> DeviceMap; - virtual ~InputServiceLinux(); DeviceMap devices_; ObserverList<Observer> observers_; |