10529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch// Copyright 2014 The Chromium Authors. All rights reserved.
20529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch// Use of this source code is governed by a BSD-style license that can be
30529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch// found in the LICENSE file.
40529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
50529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "chrome/browser/chromeos/device/input_service_proxy.h"
60529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
75f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "base/bind_helpers.h"
80529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "base/task_runner_util.h"
90529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "content/public/browser/browser_thread.h"
100529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
110529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochusing content::BrowserThread;
120529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochusing device::InputServiceLinux;
130529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
140529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochtypedef device::InputServiceLinux::InputDeviceInfo InputDeviceInfo;
150529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
160529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochnamespace chromeos {
170529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
180529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochclass InputServiceProxy::ServiceObserver : public InputServiceLinux::Observer {
190529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch public:
200529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  ServiceObserver() { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); }
210529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  virtual ~ServiceObserver() { DCHECK(CalledOnValidThread()); }
220529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
230529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  void Initialize(const base::WeakPtr<InputServiceProxy>& proxy) {
240529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    DCHECK(CalledOnValidThread());
250529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    InputServiceLinux::GetInstance()->AddObserver(this);
260529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    proxy_ = proxy;
270529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
280529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
290529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  void Shutdown() {
300529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    DCHECK(CalledOnValidThread());
310529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    if (InputServiceLinux::HasInstance())
320529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      InputServiceLinux::GetInstance()->RemoveObserver(this);
330529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    delete this;
340529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
350529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
360529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  std::vector<InputDeviceInfo> GetDevices() {
370529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    DCHECK(CalledOnValidThread());
380529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    std::vector<InputDeviceInfo> devices;
390529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    if (InputServiceLinux::HasInstance())
400529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      InputServiceLinux::GetInstance()->GetDevices(&devices);
410529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    return devices;
420529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
430529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
440529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  void GetDeviceInfo(const std::string& id,
450529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                     const InputServiceProxy::GetDeviceInfoCallback& callback) {
460529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    DCHECK(CalledOnValidThread());
470529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    bool success = false;
480529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    InputDeviceInfo info;
490529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    info.id = id;
500529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    if (InputServiceLinux::HasInstance())
510529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      success = InputServiceLinux::GetInstance()->GetDeviceInfo(id, &info);
520529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    BrowserThread::PostTask(
530529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch        BrowserThread::UI, FROM_HERE, base::Bind(callback, success, info));
540529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
550529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
560529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // InputServiceLinux::Observer implementation:
570529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  virtual void OnInputDeviceAdded(
580529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      const InputServiceLinux::InputDeviceInfo& info) OVERRIDE {
590529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    DCHECK(CalledOnValidThread());
600529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    BrowserThread::PostTask(
610529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch        BrowserThread::UI,
620529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch        FROM_HERE,
630529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch        base::Bind(&InputServiceProxy::OnDeviceAdded, proxy_, info));
640529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
650529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
660529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  virtual void OnInputDeviceRemoved(const std::string& id) OVERRIDE {
670529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    DCHECK(CalledOnValidThread());
680529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    BrowserThread::PostTask(
690529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch        BrowserThread::UI,
700529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch        FROM_HERE,
710529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch        base::Bind(&InputServiceProxy::OnDeviceRemoved, proxy_, id));
720529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
730529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
740529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch private:
750529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  bool CalledOnValidThread() const {
760529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    return BrowserThread::CurrentlyOn(BrowserThread::FILE);
770529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
780529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
790529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  base::WeakPtr<InputServiceProxy> proxy_;
800529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
810529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  DISALLOW_COPY_AND_ASSIGN(ServiceObserver);
820529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch};
830529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
840529e5d033099cbfc42635f6f6183833b09dff6eBen MurdochInputServiceProxy::InputServiceProxy()
850529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    : service_observer_(new ServiceObserver()), weak_factory_(this) {
860529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
870529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  BrowserThread::PostTask(
880529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      BrowserThread::FILE,
890529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      FROM_HERE,
900529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      base::Bind(&InputServiceProxy::ServiceObserver::Initialize,
910529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                 base::Unretained(service_observer_.get()),
920529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                 weak_factory_.GetWeakPtr()));
930529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
940529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
950529e5d033099cbfc42635f6f6183833b09dff6eBen MurdochInputServiceProxy::~InputServiceProxy() {
960529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  DCHECK(thread_checker_.CalledOnValidThread());
970529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  BrowserThread::PostTask(
980529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      BrowserThread::FILE,
990529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      FROM_HERE,
1000529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      base::Bind(&InputServiceProxy::ServiceObserver::Shutdown,
1010529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                 base::Unretained(service_observer_.release())));
1020529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
1030529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
1045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// static
1055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void InputServiceProxy::WarmUp() {
1065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  content::BrowserThread::PostTask(
1075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      content::BrowserThread::FILE,
1085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      FROM_HERE,
1095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      base::Bind(base::IgnoreResult(&InputServiceLinux::GetInstance)));
1105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
1115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1120529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochvoid InputServiceProxy::AddObserver(Observer* observer) {
1130529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  DCHECK(thread_checker_.CalledOnValidThread());
1140529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  if (observer)
1150529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    observers_.AddObserver(observer);
1160529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
1170529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
1180529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochvoid InputServiceProxy::RemoveObserver(Observer* observer) {
1190529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  DCHECK(thread_checker_.CalledOnValidThread());
1200529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  if (observer)
1210529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    observers_.RemoveObserver(observer);
1220529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
1230529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
1240529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochvoid InputServiceProxy::GetDevices(const GetDevicesCallback& callback) {
1250529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  DCHECK(thread_checker_.CalledOnValidThread());
1260529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  BrowserThread::PostTaskAndReplyWithResult(
1270529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      BrowserThread::FILE,
1280529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      FROM_HERE,
1290529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      base::Bind(&InputServiceProxy::ServiceObserver::GetDevices,
1300529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                 base::Unretained(service_observer_.get())),
1310529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      callback);
1320529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
1330529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
1340529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochvoid InputServiceProxy::GetDeviceInfo(const std::string& id,
1350529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                                      const GetDeviceInfoCallback& callback) {
1360529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  DCHECK(thread_checker_.CalledOnValidThread());
1370529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  BrowserThread::PostTask(
1380529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      BrowserThread::FILE,
1390529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      FROM_HERE,
1400529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      base::Bind(&InputServiceProxy::ServiceObserver::GetDeviceInfo,
1410529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                 base::Unretained(service_observer_.release()),
1420529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                 id,
1430529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                 callback));
1440529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
1450529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
1460529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochvoid InputServiceProxy::OnDeviceAdded(
1470529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    const InputServiceLinux::InputDeviceInfo& info) {
1480529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  DCHECK(thread_checker_.CalledOnValidThread());
1490529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  FOR_EACH_OBSERVER(Observer, observers_, OnInputDeviceAdded(info));
1500529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
1510529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
1520529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochvoid InputServiceProxy::OnDeviceRemoved(const std::string& id) {
1530529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  DCHECK(thread_checker_.CalledOnValidThread());
1540529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  FOR_EACH_OBSERVER(Observer, observers_, OnInputDeviceRemoved(id));
1550529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
1560529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
1570529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}  // namespace chromeos
158