Home | History | Annotate | Download | only in device
      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