Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(18)

Side by Side Diff: content/browser/device_orientation/provider_impl.cc

Issue 14335017: content: Use base::MessageLoop. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase Created 7 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 "content/browser/device_orientation/provider_impl.h" 5 #include "content/browser/device_orientation/provider_impl.h"
6 6
7 #include <set> 7 #include <set>
8 #include <vector> 8 #include <vector>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
11 #include "base/logging.h" 11 #include "base/logging.h"
12 #include "base/message_loop.h" 12 #include "base/message_loop.h"
13 #include "base/threading/thread.h" 13 #include "base/threading/thread.h"
14 #include "base/threading/worker_pool.h" 14 #include "base/threading/worker_pool.h"
15 15
16 namespace { 16 namespace {
17 17
18 void DeleteThread(base::Thread* thread) { 18 void DeleteThread(base::Thread* thread) {
19 delete thread; 19 delete thread;
20 } 20 }
21 21
22 } 22 }
23 23
24 namespace content { 24 namespace content {
25 25
26 class ProviderImpl::PollingThread : public base::Thread { 26 class ProviderImpl::PollingThread : public base::Thread {
27 public: 27 public:
28 PollingThread(const char* name, 28 PollingThread(const char* name,
29 base::WeakPtr<ProviderImpl> provider, 29 base::WeakPtr<ProviderImpl> provider,
30 MessageLoop* creator_loop); 30 base::MessageLoop* creator_loop);
31 virtual ~PollingThread(); 31 virtual ~PollingThread();
32 32
33 // Method for creating a DataFetcher and starting the polling, if the fetcher 33 // Method for creating a DataFetcher and starting the polling, if the fetcher
34 // can provide this type of data. 34 // can provide this type of data.
35 void Initialize(DataFetcherFactory factory, DeviceData::Type type); 35 void Initialize(DataFetcherFactory factory, DeviceData::Type type);
36 36
37 // Method for adding a type of data to poll for. 37 // Method for adding a type of data to poll for.
38 void DoAddPollingDataType(DeviceData::Type type); 38 void DoAddPollingDataType(DeviceData::Type type);
39 39
40 private: 40 private:
41 // Method for polling a DataFetcher. 41 // Method for polling a DataFetcher.
42 void DoPoll(); 42 void DoPoll();
43 void ScheduleDoPoll(); 43 void ScheduleDoPoll();
44 44
45 // Schedule a notification to the |provider_| which lives on a different 45 // Schedule a notification to the |provider_| which lives on a different
46 // thread (|creator_loop_| is its message loop). 46 // thread (|creator_loop_| is its message loop).
47 void ScheduleDoNotify(const scoped_refptr<const DeviceData>& device_data, 47 void ScheduleDoNotify(const scoped_refptr<const DeviceData>& device_data,
48 DeviceData::Type device_data_type); 48 DeviceData::Type device_data_type);
49 49
50 enum { kDesiredSamplingIntervalMs = 100 }; 50 enum { kDesiredSamplingIntervalMs = 100 };
51 base::TimeDelta SamplingInterval() const; 51 base::TimeDelta SamplingInterval() const;
52 52
53 // The Message Loop on which this object was created. 53 // The Message Loop on which this object was created.
54 // Typically the I/O loop, but may be something else during testing. 54 // Typically the I/O loop, but may be something else during testing.
55 MessageLoop* creator_loop_; 55 base::MessageLoop* creator_loop_;
56 56
57 scoped_ptr<DataFetcher> data_fetcher_; 57 scoped_ptr<DataFetcher> data_fetcher_;
58 std::map<DeviceData::Type, scoped_refptr<const DeviceData> > 58 std::map<DeviceData::Type, scoped_refptr<const DeviceData> >
59 last_device_data_map_; 59 last_device_data_map_;
60 std::set<DeviceData::Type> polling_data_types_; 60 std::set<DeviceData::Type> polling_data_types_;
61 61
62 base::WeakPtr<ProviderImpl> provider_; 62 base::WeakPtr<ProviderImpl> provider_;
63 }; 63 };
64 64
65 ProviderImpl::PollingThread::PollingThread( 65 ProviderImpl::PollingThread::PollingThread(const char* name,
66 const char* name, 66 base::WeakPtr<ProviderImpl> provider,
67 base::WeakPtr<ProviderImpl> provider, 67 base::MessageLoop* creator_loop)
68 MessageLoop* creator_loop) 68 : base::Thread(name), creator_loop_(creator_loop), provider_(provider) {}
69 : base::Thread(name),
70 creator_loop_(creator_loop),
71 provider_(provider) {
72 }
73 69
74 ProviderImpl::PollingThread::~PollingThread() { 70 ProviderImpl::PollingThread::~PollingThread() {
75 Stop(); 71 Stop();
76 } 72 }
77 73
78 void ProviderImpl::PollingThread::DoAddPollingDataType(DeviceData::Type type) { 74 void ProviderImpl::PollingThread::DoAddPollingDataType(DeviceData::Type type) {
79 DCHECK(MessageLoop::current() == message_loop()); 75 DCHECK(base::MessageLoop::current() == message_loop());
80 76
81 polling_data_types_.insert(type); 77 polling_data_types_.insert(type);
82 } 78 }
83 79
84 void ProviderImpl::PollingThread::Initialize(DataFetcherFactory factory, 80 void ProviderImpl::PollingThread::Initialize(DataFetcherFactory factory,
85 DeviceData::Type type) { 81 DeviceData::Type type) {
86 DCHECK(MessageLoop::current() == message_loop()); 82 DCHECK(base::MessageLoop::current() == message_loop());
87 83
88 if (factory != NULL) { 84 if (factory != NULL) {
89 // Try to use factory to create a fetcher that can provide this type of 85 // Try to use factory to create a fetcher that can provide this type of
90 // data. If factory creates a fetcher that provides this type of data, 86 // data. If factory creates a fetcher that provides this type of data,
91 // start polling. 87 // start polling.
92 scoped_ptr<DataFetcher> fetcher(factory()); 88 scoped_ptr<DataFetcher> fetcher(factory());
93 89
94 if (fetcher) { 90 if (fetcher) {
95 scoped_refptr<const DeviceData> device_data(fetcher->GetDeviceData(type)); 91 scoped_refptr<const DeviceData> device_data(fetcher->GetDeviceData(type));
96 if (device_data != NULL) { 92 if (device_data != NULL) {
(...skipping 11 matching lines...) Expand all
108 } 104 }
109 } 105 }
110 106
111 // When no device data can be provided. 107 // When no device data can be provided.
112 ScheduleDoNotify(NULL, type); 108 ScheduleDoNotify(NULL, type);
113 } 109 }
114 110
115 void ProviderImpl::PollingThread::ScheduleDoNotify( 111 void ProviderImpl::PollingThread::ScheduleDoNotify(
116 const scoped_refptr<const DeviceData>& device_data, 112 const scoped_refptr<const DeviceData>& device_data,
117 DeviceData::Type device_data_type) { 113 DeviceData::Type device_data_type) {
118 DCHECK(MessageLoop::current() == message_loop()); 114 DCHECK(base::MessageLoop::current() == message_loop());
119 115
120 creator_loop_->PostTask(FROM_HERE, 116 creator_loop_->PostTask(FROM_HERE,
121 base::Bind(&ProviderImpl::DoNotify, provider_, 117 base::Bind(&ProviderImpl::DoNotify, provider_,
122 device_data, device_data_type)); 118 device_data, device_data_type));
123 } 119 }
124 120
125 void ProviderImpl::PollingThread::DoPoll() { 121 void ProviderImpl::PollingThread::DoPoll() {
126 DCHECK(MessageLoop::current() == message_loop()); 122 DCHECK(base::MessageLoop::current() == message_loop());
127 123
128 // Poll the fetcher for each type of data. 124 // Poll the fetcher for each type of data.
129 typedef std::set<DeviceData::Type>::const_iterator SetIterator; 125 typedef std::set<DeviceData::Type>::const_iterator SetIterator;
130 for (SetIterator i = polling_data_types_.begin(); 126 for (SetIterator i = polling_data_types_.begin();
131 i != polling_data_types_.end(); ++i) { 127 i != polling_data_types_.end(); ++i) {
132 DeviceData::Type device_data_type = *i; 128 DeviceData::Type device_data_type = *i;
133 scoped_refptr<const DeviceData> device_data(data_fetcher_->GetDeviceData( 129 scoped_refptr<const DeviceData> device_data(data_fetcher_->GetDeviceData(
134 device_data_type)); 130 device_data_type));
135 131
136 if (device_data == NULL) { 132 if (device_data == NULL) {
137 LOG(ERROR) << "Failed to poll device data fetcher."; 133 LOG(ERROR) << "Failed to poll device data fetcher.";
138 ScheduleDoNotify(NULL, device_data_type); 134 ScheduleDoNotify(NULL, device_data_type);
139 continue; 135 continue;
140 } 136 }
141 137
142 const DeviceData* old_data = last_device_data_map_[device_data_type]; 138 const DeviceData* old_data = last_device_data_map_[device_data_type];
143 if (old_data != NULL && !device_data->ShouldFireEvent(old_data)) 139 if (old_data != NULL && !device_data->ShouldFireEvent(old_data))
144 continue; 140 continue;
145 141
146 // Update the last device data of this type and notify observers. 142 // Update the last device data of this type and notify observers.
147 last_device_data_map_[device_data_type] = device_data; 143 last_device_data_map_[device_data_type] = device_data;
148 ScheduleDoNotify(device_data, device_data_type); 144 ScheduleDoNotify(device_data, device_data_type);
149 } 145 }
150 146
151 ScheduleDoPoll(); 147 ScheduleDoPoll();
152 } 148 }
153 149
154 void ProviderImpl::PollingThread::ScheduleDoPoll() { 150 void ProviderImpl::PollingThread::ScheduleDoPoll() {
155 DCHECK(MessageLoop::current() == message_loop()); 151 DCHECK(base::MessageLoop::current() == message_loop());
156 152
157 message_loop()->PostDelayedTask( 153 message_loop()->PostDelayedTask(
158 FROM_HERE, 154 FROM_HERE,
159 base::Bind(&PollingThread::DoPoll, base::Unretained(this)), 155 base::Bind(&PollingThread::DoPoll, base::Unretained(this)),
160 SamplingInterval()); 156 SamplingInterval());
161 } 157 }
162 158
163 base::TimeDelta ProviderImpl::PollingThread::SamplingInterval() const { 159 base::TimeDelta ProviderImpl::PollingThread::SamplingInterval() const {
164 DCHECK(MessageLoop::current() == message_loop()); 160 DCHECK(base::MessageLoop::current() == message_loop());
165 DCHECK(data_fetcher_.get()); 161 DCHECK(data_fetcher_.get());
166 162
167 // TODO(erg): There used to be unused code here, that called a default 163 // TODO(erg): There used to be unused code here, that called a default
168 // implementation on the DataFetcherInterface that was never defined. I'm 164 // implementation on the DataFetcherInterface that was never defined. I'm
169 // removing unused methods from headers. 165 // removing unused methods from headers.
170 return base::TimeDelta::FromMilliseconds(kDesiredSamplingIntervalMs); 166 return base::TimeDelta::FromMilliseconds(kDesiredSamplingIntervalMs);
171 } 167 }
172 168
173 ProviderImpl::ProviderImpl(DataFetcherFactory factory) 169 ProviderImpl::ProviderImpl(DataFetcherFactory factory)
174 : creator_loop_(MessageLoop::current()), 170 : creator_loop_(base::MessageLoop::current()),
175 factory_(factory), 171 factory_(factory),
176 weak_factory_(this), 172 weak_factory_(this),
177 polling_thread_(NULL) { 173 polling_thread_(NULL) {
178 } 174 }
179 175
180 ProviderImpl::~ProviderImpl() { 176 ProviderImpl::~ProviderImpl() {
181 Stop(); 177 Stop();
182 } 178 }
183 179
184 void ProviderImpl::ScheduleDoAddPollingDataType(DeviceData::Type type) { 180 void ProviderImpl::ScheduleDoAddPollingDataType(DeviceData::Type type) {
185 DCHECK(MessageLoop::current() == creator_loop_); 181 DCHECK(base::MessageLoop::current() == creator_loop_);
186 182
187 MessageLoop* polling_loop = polling_thread_->message_loop(); 183 base::MessageLoop* polling_loop = polling_thread_->message_loop();
188 polling_loop->PostTask(FROM_HERE, 184 polling_loop->PostTask(FROM_HERE,
189 base::Bind(&PollingThread::DoAddPollingDataType, 185 base::Bind(&PollingThread::DoAddPollingDataType,
190 base::Unretained(polling_thread_), 186 base::Unretained(polling_thread_),
191 type)); 187 type));
192 } 188 }
193 189
194 void ProviderImpl::AddObserver(Observer* observer) { 190 void ProviderImpl::AddObserver(Observer* observer) {
195 DCHECK(MessageLoop::current() == creator_loop_); 191 DCHECK(base::MessageLoop::current() == creator_loop_);
196 192
197 DeviceData::Type type = observer->device_data_type(); 193 DeviceData::Type type = observer->device_data_type();
198 194
199 observers_.insert(observer); 195 observers_.insert(observer);
200 if (observers_.size() == 1) 196 if (observers_.size() == 1)
201 Start(type); 197 Start(type);
202 else { 198 else {
203 // Notify observer of most recent notification if one exists. 199 // Notify observer of most recent notification if one exists.
204 const DeviceData *last_notification = last_notifications_map_[type]; 200 const DeviceData *last_notification = last_notifications_map_[type];
205 if (last_notification != NULL) 201 if (last_notification != NULL)
206 observer->OnDeviceDataUpdate(last_notification, type); 202 observer->OnDeviceDataUpdate(last_notification, type);
207 } 203 }
208 204
209 ScheduleDoAddPollingDataType(type); 205 ScheduleDoAddPollingDataType(type);
210 } 206 }
211 207
212 void ProviderImpl::RemoveObserver(Observer* observer) { 208 void ProviderImpl::RemoveObserver(Observer* observer) {
213 DCHECK(MessageLoop::current() == creator_loop_); 209 DCHECK(base::MessageLoop::current() == creator_loop_);
214 210
215 observers_.erase(observer); 211 observers_.erase(observer);
216 if (observers_.empty()) 212 if (observers_.empty())
217 Stop(); 213 Stop();
218 } 214 }
219 215
220 void ProviderImpl::Start(DeviceData::Type type) { 216 void ProviderImpl::Start(DeviceData::Type type) {
221 DCHECK(MessageLoop::current() == creator_loop_); 217 DCHECK(base::MessageLoop::current() == creator_loop_);
222 DCHECK(!polling_thread_); 218 DCHECK(!polling_thread_);
223 219
224 polling_thread_ = new PollingThread("Device data polling thread", 220 polling_thread_ = new PollingThread("Device data polling thread",
225 weak_factory_.GetWeakPtr(), 221 weak_factory_.GetWeakPtr(),
226 creator_loop_); 222 creator_loop_);
227 #if defined(OS_WIN) 223 #if defined(OS_WIN)
228 polling_thread_->init_com_with_mta(true); 224 polling_thread_->init_com_with_mta(true);
229 #endif 225 #endif
230 if (!polling_thread_->Start()) { 226 if (!polling_thread_->Start()) {
231 LOG(ERROR) << "Failed to start device data polling thread"; 227 LOG(ERROR) << "Failed to start device data polling thread";
232 delete polling_thread_; 228 delete polling_thread_;
233 polling_thread_ = NULL; 229 polling_thread_ = NULL;
234 return; 230 return;
235 } 231 }
236 ScheduleInitializePollingThread(type); 232 ScheduleInitializePollingThread(type);
237 } 233 }
238 234
239 void ProviderImpl::Stop() { 235 void ProviderImpl::Stop() {
240 DCHECK(MessageLoop::current() == creator_loop_); 236 DCHECK(base::MessageLoop::current() == creator_loop_);
241 237
242 weak_factory_.InvalidateWeakPtrs(); 238 weak_factory_.InvalidateWeakPtrs();
243 if (polling_thread_) { 239 if (polling_thread_) {
244 polling_thread_->StopSoon(); 240 polling_thread_->StopSoon();
245 bool posted = base::WorkerPool::PostTask( 241 bool posted = base::WorkerPool::PostTask(
246 FROM_HERE, 242 FROM_HERE,
247 base::Bind(&DeleteThread, base::Unretained(polling_thread_)), 243 base::Bind(&DeleteThread, base::Unretained(polling_thread_)),
248 true /* task is slow */); 244 true /* task is slow */);
249 DCHECK(posted); 245 DCHECK(posted);
250 polling_thread_ = NULL; 246 polling_thread_ = NULL;
251 } 247 }
252 } 248 }
253 249
254 void ProviderImpl::ScheduleInitializePollingThread( 250 void ProviderImpl::ScheduleInitializePollingThread(
255 DeviceData::Type device_data_type) { 251 DeviceData::Type device_data_type) {
256 DCHECK(MessageLoop::current() == creator_loop_); 252 DCHECK(base::MessageLoop::current() == creator_loop_);
257 253
258 MessageLoop* polling_loop = polling_thread_->message_loop(); 254 base::MessageLoop* polling_loop = polling_thread_->message_loop();
259 polling_loop->PostTask(FROM_HERE, 255 polling_loop->PostTask(FROM_HERE,
260 base::Bind(&PollingThread::Initialize, 256 base::Bind(&PollingThread::Initialize,
261 base::Unretained(polling_thread_), 257 base::Unretained(polling_thread_),
262 factory_, 258 factory_,
263 device_data_type)); 259 device_data_type));
264 } 260 }
265 261
266 void ProviderImpl::DoNotify(const scoped_refptr<const DeviceData>& data, 262 void ProviderImpl::DoNotify(const scoped_refptr<const DeviceData>& data,
267 DeviceData::Type device_data_type) { 263 DeviceData::Type device_data_type) {
268 DCHECK(MessageLoop::current() == creator_loop_); 264 DCHECK(base::MessageLoop::current() == creator_loop_);
269 265
270 // Update last notification of this type. 266 // Update last notification of this type.
271 last_notifications_map_[device_data_type] = data; 267 last_notifications_map_[device_data_type] = data;
272 268
273 // Notify observers of this type of the new data. 269 // Notify observers of this type of the new data.
274 typedef std::set<Observer*>::const_iterator ConstIterator; 270 typedef std::set<Observer*>::const_iterator ConstIterator;
275 for (ConstIterator i = observers_.begin(); i != observers_.end(); ++i) { 271 for (ConstIterator i = observers_.begin(); i != observers_.end(); ++i) {
276 if ((*i)->device_data_type() == device_data_type) 272 if ((*i)->device_data_type() == device_data_type)
277 (*i)->OnDeviceDataUpdate(data.get(), device_data_type); 273 (*i)->OnDeviceDataUpdate(data.get(), device_data_type);
278 } 274 }
279 275
280 if (data == NULL) { 276 if (data == NULL) {
281 // Notify observers exactly once about failure to provide data. 277 // Notify observers exactly once about failure to provide data.
282 typedef std::set<Observer*>::iterator Iterator; 278 typedef std::set<Observer*>::iterator Iterator;
283 Iterator i = observers_.begin(); 279 Iterator i = observers_.begin();
284 while (i != observers_.end()) { 280 while (i != observers_.end()) {
285 Iterator current = i++; 281 Iterator current = i++;
286 if ((*current)->device_data_type() == device_data_type) 282 if ((*current)->device_data_type() == device_data_type)
287 observers_.erase(current); 283 observers_.erase(current);
288 } 284 }
289 285
290 if (observers_.empty()) 286 if (observers_.empty())
291 Stop(); 287 Stop();
292 } 288 }
293 } 289 }
294 290
295 291
296 } // namespace content 292 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/device_monitor_linux.cc ('k') | content/browser/device_orientation/provider_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698