OLD | NEW |
---|---|
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/chromeos/device/input_service_proxy.h" | 5 #include "chrome/browser/chromeos/device/input_service_proxy.h" |
6 | 6 |
7 #include "base/bind_helpers.h" | 7 #include "base/bind_helpers.h" |
8 #include "base/macros.h" | 8 #include "base/macros.h" |
9 #include "base/sequence_checker.h" | |
9 #include "base/task_runner_util.h" | 10 #include "base/task_runner_util.h" |
11 #include "base/task_scheduler/lazy_task_runner.h" | |
12 #include "base/task_scheduler/post_task.h" | |
10 #include "content/public/browser/browser_thread.h" | 13 #include "content/public/browser/browser_thread.h" |
11 | 14 |
12 using content::BrowserThread; | 15 using content::BrowserThread; |
13 using device::InputServiceLinux; | 16 using device::InputServiceLinux; |
14 | 17 |
15 typedef device::InputServiceLinux::InputDeviceInfo InputDeviceInfo; | 18 typedef device::InputServiceLinux::InputDeviceInfo InputDeviceInfo; |
achuithb
2017/06/19 22:34:42
Does it make sense to move this into the anonymous
xiyuan
2017/06/19 23:00:26
Moved and changed typedef -> using.
| |
16 | 19 |
17 namespace chromeos { | 20 namespace chromeos { |
18 | 21 |
19 // static | 22 namespace { |
20 BrowserThread::ID InputServiceProxy::thread_identifier_ = BrowserThread::FILE; | 23 |
24 bool use_ui_thread_for_test = false; | |
25 | |
26 // SequencedTaskRunner could be used after InputServiceLinux and friends | |
27 // are updated to check on sequence instead of thread. | |
28 base::LazySingleThreadTaskRunner default_input_service_task_runner = | |
29 LAZY_SINGLE_THREAD_TASK_RUNNER_INITIALIZER( | |
30 base::TaskTraits({base::TaskPriority::BACKGROUND, base::MayBlock()}), | |
31 base::SingleThreadTaskRunnerThreadMode::SHARED); | |
32 | |
33 } // namespace | |
21 | 34 |
22 class InputServiceProxy::ServiceObserver : public InputServiceLinux::Observer { | 35 class InputServiceProxy::ServiceObserver : public InputServiceLinux::Observer { |
23 public: | 36 public: |
24 ServiceObserver() { DCHECK_CURRENTLY_ON(BrowserThread::UI); } | 37 ServiceObserver() { |
25 ~ServiceObserver() override { DCHECK(CalledOnValidThread()); } | 38 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
39 | |
40 // Detach since this object is constructed on UI thread and forever after | |
41 // used from another sequence. | |
42 DETACH_FROM_SEQUENCE(sequence_checker_); | |
43 } | |
44 ~ServiceObserver() override { | |
45 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); | |
46 } | |
26 | 47 |
27 void Initialize(const base::WeakPtr<InputServiceProxy>& proxy) { | 48 void Initialize(const base::WeakPtr<InputServiceProxy>& proxy) { |
28 DCHECK(CalledOnValidThread()); | 49 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
29 InputServiceLinux::GetInstance()->AddObserver(this); | 50 InputServiceLinux::GetInstance()->AddObserver(this); |
30 proxy_ = proxy; | 51 proxy_ = proxy; |
31 } | 52 } |
32 | 53 |
33 void Shutdown() { | 54 void Shutdown() { |
34 DCHECK(CalledOnValidThread()); | 55 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
35 if (InputServiceLinux::HasInstance()) | 56 if (InputServiceLinux::HasInstance()) |
36 InputServiceLinux::GetInstance()->RemoveObserver(this); | 57 InputServiceLinux::GetInstance()->RemoveObserver(this); |
37 delete this; | 58 delete this; |
38 } | 59 } |
39 | 60 |
40 std::vector<InputDeviceInfo> GetDevices() { | 61 std::vector<InputDeviceInfo> GetDevices() { |
41 DCHECK(CalledOnValidThread()); | 62 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
42 std::vector<InputDeviceInfo> devices; | 63 std::vector<InputDeviceInfo> devices; |
43 if (InputServiceLinux::HasInstance()) | 64 if (InputServiceLinux::HasInstance()) |
44 InputServiceLinux::GetInstance()->GetDevices(&devices); | 65 InputServiceLinux::GetInstance()->GetDevices(&devices); |
45 return devices; | 66 return devices; |
46 } | 67 } |
47 | 68 |
48 void GetDeviceInfo(const std::string& id, | 69 void GetDeviceInfo(const std::string& id, |
49 const InputServiceProxy::GetDeviceInfoCallback& callback) { | 70 const InputServiceProxy::GetDeviceInfoCallback& callback) { |
50 DCHECK(CalledOnValidThread()); | 71 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
51 bool success = false; | 72 bool success = false; |
52 InputDeviceInfo info; | 73 InputDeviceInfo info; |
53 info.id = id; | 74 info.id = id; |
54 if (InputServiceLinux::HasInstance()) | 75 if (InputServiceLinux::HasInstance()) |
55 success = InputServiceLinux::GetInstance()->GetDeviceInfo(id, &info); | 76 success = InputServiceLinux::GetInstance()->GetDeviceInfo(id, &info); |
56 BrowserThread::PostTask( | 77 BrowserThread::PostTask( |
57 BrowserThread::UI, FROM_HERE, base::Bind(callback, success, info)); | 78 BrowserThread::UI, FROM_HERE, base::Bind(callback, success, info)); |
58 } | 79 } |
59 | 80 |
60 // InputServiceLinux::Observer implementation: | 81 // InputServiceLinux::Observer implementation: |
61 void OnInputDeviceAdded( | 82 void OnInputDeviceAdded( |
62 const InputServiceLinux::InputDeviceInfo& info) override { | 83 const InputServiceLinux::InputDeviceInfo& info) override { |
63 DCHECK(CalledOnValidThread()); | 84 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
64 BrowserThread::PostTask( | 85 BrowserThread::PostTask( |
65 BrowserThread::UI, | 86 BrowserThread::UI, |
66 FROM_HERE, | 87 FROM_HERE, |
67 base::Bind(&InputServiceProxy::OnDeviceAdded, proxy_, info)); | 88 base::Bind(&InputServiceProxy::OnDeviceAdded, proxy_, info)); |
68 } | 89 } |
69 | 90 |
70 void OnInputDeviceRemoved(const std::string& id) override { | 91 void OnInputDeviceRemoved(const std::string& id) override { |
71 DCHECK(CalledOnValidThread()); | 92 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
72 BrowserThread::PostTask( | 93 BrowserThread::PostTask( |
73 BrowserThread::UI, | 94 BrowserThread::UI, |
74 FROM_HERE, | 95 FROM_HERE, |
75 base::Bind(&InputServiceProxy::OnDeviceRemoved, proxy_, id)); | 96 base::Bind(&InputServiceProxy::OnDeviceRemoved, proxy_, id)); |
76 } | 97 } |
77 | 98 |
78 private: | 99 private: |
79 bool CalledOnValidThread() const { | |
80 return BrowserThread::CurrentlyOn(InputServiceProxy::thread_identifier_); | |
81 } | |
82 | |
83 base::WeakPtr<InputServiceProxy> proxy_; | 100 base::WeakPtr<InputServiceProxy> proxy_; |
101 SEQUENCE_CHECKER(sequence_checker_); | |
84 | 102 |
85 DISALLOW_COPY_AND_ASSIGN(ServiceObserver); | 103 DISALLOW_COPY_AND_ASSIGN(ServiceObserver); |
86 }; | 104 }; |
87 | 105 |
88 InputServiceProxy::InputServiceProxy() | 106 InputServiceProxy::InputServiceProxy() |
89 : service_observer_(new ServiceObserver()), | 107 : service_observer_(new ServiceObserver()), |
90 task_runner_(BrowserThread::GetTaskRunnerForThread(thread_identifier_)), | |
91 weak_factory_(this) { | 108 weak_factory_(this) { |
92 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 109 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
93 task_runner_->PostTask( | 110 GetInputServiceTaskRunner()->PostTask( |
94 FROM_HERE, | 111 FROM_HERE, base::Bind(&InputServiceProxy::ServiceObserver::Initialize, |
95 base::Bind(&InputServiceProxy::ServiceObserver::Initialize, | 112 base::Unretained(service_observer_.get()), |
96 base::Unretained(service_observer_.get()), | 113 weak_factory_.GetWeakPtr())); |
97 weak_factory_.GetWeakPtr())); | |
98 } | 114 } |
99 | 115 |
100 InputServiceProxy::~InputServiceProxy() { | 116 InputServiceProxy::~InputServiceProxy() { |
101 DCHECK(thread_checker_.CalledOnValidThread()); | 117 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); |
102 task_runner_->PostTask( | 118 GetInputServiceTaskRunner()->PostTask( |
103 FROM_HERE, | 119 FROM_HERE, base::Bind(&InputServiceProxy::ServiceObserver::Shutdown, |
104 base::Bind(&InputServiceProxy::ServiceObserver::Shutdown, | 120 base::Unretained(service_observer_.release()))); |
105 base::Unretained(service_observer_.release()))); | |
106 } | 121 } |
107 | 122 |
108 void InputServiceProxy::AddObserver(Observer* observer) { | 123 void InputServiceProxy::AddObserver(Observer* observer) { |
109 DCHECK(thread_checker_.CalledOnValidThread()); | 124 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); |
110 if (observer) | 125 if (observer) |
111 observers_.AddObserver(observer); | 126 observers_.AddObserver(observer); |
112 } | 127 } |
113 | 128 |
114 void InputServiceProxy::RemoveObserver(Observer* observer) { | 129 void InputServiceProxy::RemoveObserver(Observer* observer) { |
115 DCHECK(thread_checker_.CalledOnValidThread()); | 130 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); |
116 if (observer) | 131 if (observer) |
117 observers_.RemoveObserver(observer); | 132 observers_.RemoveObserver(observer); |
118 } | 133 } |
119 | 134 |
120 void InputServiceProxy::GetDevices(const GetDevicesCallback& callback) { | 135 void InputServiceProxy::GetDevices(const GetDevicesCallback& callback) { |
121 DCHECK(thread_checker_.CalledOnValidThread()); | 136 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); |
122 base::PostTaskAndReplyWithResult( | 137 base::PostTaskAndReplyWithResult( |
123 task_runner_.get(), | 138 GetInputServiceTaskRunner().get(), FROM_HERE, |
124 FROM_HERE, | |
125 base::Bind(&InputServiceProxy::ServiceObserver::GetDevices, | 139 base::Bind(&InputServiceProxy::ServiceObserver::GetDevices, |
126 base::Unretained(service_observer_.get())), | 140 base::Unretained(service_observer_.get())), |
127 callback); | 141 callback); |
128 } | 142 } |
129 | 143 |
130 void InputServiceProxy::GetDeviceInfo(const std::string& id, | 144 void InputServiceProxy::GetDeviceInfo(const std::string& id, |
131 const GetDeviceInfoCallback& callback) { | 145 const GetDeviceInfoCallback& callback) { |
132 DCHECK(thread_checker_.CalledOnValidThread()); | 146 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); |
133 task_runner_->PostTask( | 147 GetInputServiceTaskRunner()->PostTask( |
134 FROM_HERE, | 148 FROM_HERE, |
135 base::Bind(&InputServiceProxy::ServiceObserver::GetDeviceInfo, | 149 base::Bind(&InputServiceProxy::ServiceObserver::GetDeviceInfo, |
136 base::Unretained(service_observer_.release()), | 150 base::Unretained(service_observer_.get()), id, callback)); |
137 id, | |
138 callback)); | |
139 } | 151 } |
140 | 152 |
141 // static | 153 // static |
142 void InputServiceProxy::SetThreadIdForTesting(BrowserThread::ID thread_id) { | 154 scoped_refptr<base::TaskRunner> InputServiceProxy::GetInputServiceTaskRunner() { |
143 InputServiceProxy::thread_identifier_ = thread_id; | 155 if (use_ui_thread_for_test) |
156 return BrowserThread::GetTaskRunnerForThread(BrowserThread::UI); | |
157 | |
158 return default_input_service_task_runner.Get(); | |
159 } | |
160 | |
161 // static | |
162 void InputServiceProxy::SetUseUIThreadForTesting(bool use_ui_thread) { | |
163 use_ui_thread_for_test = use_ui_thread; | |
144 } | 164 } |
145 | 165 |
146 void InputServiceProxy::OnDeviceAdded( | 166 void InputServiceProxy::OnDeviceAdded( |
147 const InputServiceLinux::InputDeviceInfo& info) { | 167 const InputServiceLinux::InputDeviceInfo& info) { |
148 DCHECK(thread_checker_.CalledOnValidThread()); | 168 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); |
149 for (auto& observer : observers_) | 169 for (auto& observer : observers_) |
150 observer.OnInputDeviceAdded(info); | 170 observer.OnInputDeviceAdded(info); |
151 } | 171 } |
152 | 172 |
153 void InputServiceProxy::OnDeviceRemoved(const std::string& id) { | 173 void InputServiceProxy::OnDeviceRemoved(const std::string& id) { |
154 DCHECK(thread_checker_.CalledOnValidThread()); | 174 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); |
155 for (auto& observer : observers_) | 175 for (auto& observer : observers_) |
156 observer.OnInputDeviceRemoved(id); | 176 observer.OnInputDeviceRemoved(id); |
157 } | 177 } |
158 | 178 |
159 } // namespace chromeos | 179 } // namespace chromeos |
OLD | NEW |