1 // Copyright 2014 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/device/input_service_proxy.h" 6 7 #include "base/bind_helpers.h" 8 #include "base/task_runner_util.h" 9 #include "content/public/browser/browser_thread.h" 10 11 using content::BrowserThread; 12 using device::InputServiceLinux; 13 14 typedef device::InputServiceLinux::InputDeviceInfo InputDeviceInfo; 15 16 namespace chromeos { 17 18 class InputServiceProxy::ServiceObserver : public InputServiceLinux::Observer { 19 public: 20 ServiceObserver() { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); } 21 virtual ~ServiceObserver() { DCHECK(CalledOnValidThread()); } 22 23 void Initialize(const base::WeakPtr<InputServiceProxy>& proxy) { 24 DCHECK(CalledOnValidThread()); 25 InputServiceLinux::GetInstance()->AddObserver(this); 26 proxy_ = proxy; 27 } 28 29 void Shutdown() { 30 DCHECK(CalledOnValidThread()); 31 if (InputServiceLinux::HasInstance()) 32 InputServiceLinux::GetInstance()->RemoveObserver(this); 33 delete this; 34 } 35 36 std::vector<InputDeviceInfo> GetDevices() { 37 DCHECK(CalledOnValidThread()); 38 std::vector<InputDeviceInfo> devices; 39 if (InputServiceLinux::HasInstance()) 40 InputServiceLinux::GetInstance()->GetDevices(&devices); 41 return devices; 42 } 43 44 void GetDeviceInfo(const std::string& id, 45 const InputServiceProxy::GetDeviceInfoCallback& callback) { 46 DCHECK(CalledOnValidThread()); 47 bool success = false; 48 InputDeviceInfo info; 49 info.id = id; 50 if (InputServiceLinux::HasInstance()) 51 success = InputServiceLinux::GetInstance()->GetDeviceInfo(id, &info); 52 BrowserThread::PostTask( 53 BrowserThread::UI, FROM_HERE, base::Bind(callback, success, info)); 54 } 55 56 // InputServiceLinux::Observer implementation: 57 virtual void OnInputDeviceAdded( 58 const InputServiceLinux::InputDeviceInfo& info) OVERRIDE { 59 DCHECK(CalledOnValidThread()); 60 BrowserThread::PostTask( 61 BrowserThread::UI, 62 FROM_HERE, 63 base::Bind(&InputServiceProxy::OnDeviceAdded, proxy_, info)); 64 } 65 66 virtual void OnInputDeviceRemoved(const std::string& id) OVERRIDE { 67 DCHECK(CalledOnValidThread()); 68 BrowserThread::PostTask( 69 BrowserThread::UI, 70 FROM_HERE, 71 base::Bind(&InputServiceProxy::OnDeviceRemoved, proxy_, id)); 72 } 73 74 private: 75 bool CalledOnValidThread() const { 76 return BrowserThread::CurrentlyOn(BrowserThread::FILE); 77 } 78 79 base::WeakPtr<InputServiceProxy> proxy_; 80 81 DISALLOW_COPY_AND_ASSIGN(ServiceObserver); 82 }; 83 84 InputServiceProxy::InputServiceProxy() 85 : service_observer_(new ServiceObserver()), weak_factory_(this) { 86 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 87 BrowserThread::PostTask( 88 BrowserThread::FILE, 89 FROM_HERE, 90 base::Bind(&InputServiceProxy::ServiceObserver::Initialize, 91 base::Unretained(service_observer_.get()), 92 weak_factory_.GetWeakPtr())); 93 } 94 95 InputServiceProxy::~InputServiceProxy() { 96 DCHECK(thread_checker_.CalledOnValidThread()); 97 BrowserThread::PostTask( 98 BrowserThread::FILE, 99 FROM_HERE, 100 base::Bind(&InputServiceProxy::ServiceObserver::Shutdown, 101 base::Unretained(service_observer_.release()))); 102 } 103 104 // static 105 void InputServiceProxy::WarmUp() { 106 content::BrowserThread::PostTask( 107 content::BrowserThread::FILE, 108 FROM_HERE, 109 base::Bind(base::IgnoreResult(&InputServiceLinux::GetInstance))); 110 } 111 112 void InputServiceProxy::AddObserver(Observer* observer) { 113 DCHECK(thread_checker_.CalledOnValidThread()); 114 if (observer) 115 observers_.AddObserver(observer); 116 } 117 118 void InputServiceProxy::RemoveObserver(Observer* observer) { 119 DCHECK(thread_checker_.CalledOnValidThread()); 120 if (observer) 121 observers_.RemoveObserver(observer); 122 } 123 124 void InputServiceProxy::GetDevices(const GetDevicesCallback& callback) { 125 DCHECK(thread_checker_.CalledOnValidThread()); 126 BrowserThread::PostTaskAndReplyWithResult( 127 BrowserThread::FILE, 128 FROM_HERE, 129 base::Bind(&InputServiceProxy::ServiceObserver::GetDevices, 130 base::Unretained(service_observer_.get())), 131 callback); 132 } 133 134 void InputServiceProxy::GetDeviceInfo(const std::string& id, 135 const GetDeviceInfoCallback& callback) { 136 DCHECK(thread_checker_.CalledOnValidThread()); 137 BrowserThread::PostTask( 138 BrowserThread::FILE, 139 FROM_HERE, 140 base::Bind(&InputServiceProxy::ServiceObserver::GetDeviceInfo, 141 base::Unretained(service_observer_.release()), 142 id, 143 callback)); 144 } 145 146 void InputServiceProxy::OnDeviceAdded( 147 const InputServiceLinux::InputDeviceInfo& info) { 148 DCHECK(thread_checker_.CalledOnValidThread()); 149 FOR_EACH_OBSERVER(Observer, observers_, OnInputDeviceAdded(info)); 150 } 151 152 void InputServiceProxy::OnDeviceRemoved(const std::string& id) { 153 DCHECK(thread_checker_.CalledOnValidThread()); 154 FOR_EACH_OBSERVER(Observer, observers_, OnInputDeviceRemoved(id)); 155 } 156 157 } // namespace chromeos 158