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

Unified Diff: content/browser/device_orientation/provider_impl.cc

Issue 10755002: Refactors DeviceOrientation to make it more extensible (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Removing unused function IsEmpty Created 8 years, 5 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 side-by-side diff with in-line comments
Download patch
Index: content/browser/device_orientation/provider_impl.cc
diff --git a/content/browser/device_orientation/provider_impl.cc b/content/browser/device_orientation/provider_impl.cc
index fab78a11a42733926495eaa1902bc52d879a21bb..acde10691cc0a4593064799aab0d9ef29d30e5be 100644
--- a/content/browser/device_orientation/provider_impl.cc
+++ b/content/browser/device_orientation/provider_impl.cc
@@ -2,7 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include <cmath>
+#include "content/browser/device_orientation/provider_impl.h"
+
#include <set>
#include <vector>
@@ -12,7 +13,6 @@
#include "base/threading/thread.h"
#include "base/threading/thread_restrictions.h"
#include "content/browser/device_orientation/orientation.h"
-#include "content/browser/device_orientation/provider_impl.h"
namespace device_orientation {
@@ -29,11 +29,21 @@ ProviderImpl::~ProviderImpl() {
void ProviderImpl::AddObserver(Observer* observer) {
DCHECK(MessageLoop::current() == creator_loop_);
+ DeviceData::Type type = observer->device_data_type();
+
observers_.insert(observer);
if (observers_.size() == 1)
- Start();
- else
- observer->OnOrientationUpdate(last_notification_);
+ Start(type);
+ else {
+ // Notify observer of most recent notification if one exists.
+ typedef std::map<DeviceData::Type, scoped_refptr<const DeviceData> >::
+ const_iterator Iterator;
+ Iterator iter = last_notifications_map_.find(type);
+ if (iter != last_notifications_map_.end())
+ observer->OnDeviceDataUpdate((*iter).second, type);
+ }
+
+ ScheduleDoAddPollingDataType(type);
}
void ProviderImpl::RemoveObserver(Observer* observer) {
@@ -44,17 +54,22 @@ void ProviderImpl::RemoveObserver(Observer* observer) {
Stop();
}
-void ProviderImpl::Start() {
+void ProviderImpl::Start(DeviceData::Type type) {
DCHECK(MessageLoop::current() == creator_loop_);
DCHECK(!polling_thread_.get());
- polling_thread_.reset(new base::Thread("Device orientation polling thread"));
+ // Reset members used on polling thread.
+ last_device_data_map_.reset(new std::map<DeviceData::Type,
+ scoped_refptr<const DeviceData> >);
+ polling_data_types_.clear();
+
+ polling_thread_.reset(new base::Thread("Device data polling thread"));
if (!polling_thread_->Start()) {
- LOG(ERROR) << "Failed to start device orientation polling thread";
+ LOG(ERROR) << "Failed to start device data polling thread";
polling_thread_.reset();
return;
}
- ScheduleInitializePollingThread();
+ ScheduleInitializePollingThread(type);
}
void ProviderImpl::Stop() {
@@ -67,24 +82,45 @@ void ProviderImpl::Stop() {
data_fetcher_.reset();
}
+void ProviderImpl::DoAddPollingDataType(DeviceData::Type type) {
+ DCHECK(MessageLoop::current() == polling_thread_->message_loop());
+
+ polling_data_types_.insert(type);
+}
+
+void ProviderImpl::ScheduleDoAddPollingDataType(DeviceData::Type type) {
+ DCHECK(MessageLoop::current() == creator_loop_);
+
+ MessageLoop* polling_loop = polling_thread_->message_loop();
+ polling_loop->PostTask(FROM_HERE,
+ base::Bind(&ProviderImpl::DoAddPollingDataType,
+ this,
+ type));
+}
+
void ProviderImpl::DoInitializePollingThread(
- const std::vector<DataFetcherFactory>& factories) {
+ const std::vector<DataFetcherFactory>& factories,
+ DeviceData::Type device_data_type) {
DCHECK(MessageLoop::current() == polling_thread_->message_loop());
typedef std::vector<DataFetcherFactory>::const_iterator Iterator;
- for (Iterator i = factories_.begin(), e = factories_.end(); i != e; ++i) {
+ for (Iterator i = factories_.begin(); i != factories_.end(); ++i) {
DataFetcherFactory factory = *i;
scoped_ptr<DataFetcher> fetcher(factory());
- Orientation orientation;
- if (fetcher.get() && fetcher->GetOrientation(&orientation)) {
+ if (!fetcher.get())
+ continue;
+
+ scoped_refptr<const DeviceData> device_data(fetcher->GetDeviceData(
+ device_data_type));
+ if (device_data != NULL) {
// Pass ownership of fetcher to provider_.
data_fetcher_.swap(fetcher);
- last_orientation_ = orientation;
+ last_device_data_map_->insert(std::pair<DeviceData::Type,
+ scoped_refptr<const DeviceData> >(device_data_type, device_data));
// Notify observers.
- if (!orientation.is_empty())
- ScheduleDoNotify(orientation);
+ ScheduleDoNotify(device_data, device_data_type);
// Start polling.
ScheduleDoPoll();
@@ -92,58 +128,94 @@ void ProviderImpl::DoInitializePollingThread(
}
}
- // When no orientation data can be provided.
- ScheduleDoNotify(Orientation::Empty());
+ // When no device data can be provided.
+ ScheduleDoNotify(NULL, device_data_type);
}
-void ProviderImpl::ScheduleInitializePollingThread() {
+void ProviderImpl::ScheduleInitializePollingThread(
+ DeviceData::Type device_data_type) {
DCHECK(MessageLoop::current() == creator_loop_);
MessageLoop* polling_loop = polling_thread_->message_loop();
polling_loop->PostTask(FROM_HERE,
base::Bind(&ProviderImpl::DoInitializePollingThread,
this,
- factories_));
+ factories_,
+ device_data_type));
}
-void ProviderImpl::DoNotify(const Orientation& orientation) {
+void ProviderImpl::DoNotify(const DeviceData* device_data,
+ DeviceData::Type device_data_type) {
DCHECK(MessageLoop::current() == creator_loop_);
- last_notification_ = orientation;
+ scoped_refptr<const DeviceData> data(device_data);
- typedef std::set<Observer*>::const_iterator Iterator;
- for (Iterator i = observers_.begin(), e = observers_.end(); i != e; ++i)
- (*i)->OnOrientationUpdate(orientation);
+ // Update last notification of this type.
+ if (data != NULL)
hans 2012/07/30 16:12:52 do we need this if statement?
aousterh 2012/08/03 11:08:14 Done.
+ last_notifications_map_[device_data_type] = data;
- if (orientation.is_empty()) {
- // Notify observers about failure to provide data exactly once.
- observers_.clear();
- Stop();
+ // Notify observers of this type of the new data.
+ typedef std::set<Observer*>::const_iterator ConstIterator;
+ for (ConstIterator i = observers_.begin(); i != observers_.end(); ++i) {
+ if ((*i)->device_data_type() == device_data_type)
+ (*i)->OnDeviceDataUpdate(data.get(), device_data_type);
+ }
+
+ if (data == NULL) {
+ // Notify observers exactly once about failure to provide data.
+ typedef std::set<Observer*>::iterator Iterator;
+ Iterator i = observers_.begin();
+ while (i != observers_.end()) {
+ Iterator current = i++;
+ if ((*current)->device_data_type() == device_data_type)
+ observers_.erase(current);
+ }
+
+ if (observers_.empty())
+ Stop();
}
}
-void ProviderImpl::ScheduleDoNotify(const Orientation& orientation) {
+void ProviderImpl::ScheduleDoNotify(const DeviceData* device_data,
+ DeviceData::Type device_data_type) {
DCHECK(MessageLoop::current() == polling_thread_->message_loop());
- creator_loop_->PostTask(
- FROM_HERE, base::Bind(&ProviderImpl::DoNotify, this, orientation));
+ creator_loop_->PostTask(FROM_HERE,
+ base::Bind(&ProviderImpl::DoNotify, this,
+ device_data, device_data_type));
}
void ProviderImpl::DoPoll() {
DCHECK(MessageLoop::current() == polling_thread_->message_loop());
- Orientation orientation;
- if (!data_fetcher_->GetOrientation(&orientation)) {
- LOG(ERROR) << "Failed to poll device orientation data fetcher.";
+ // Poll the fetcher for each type of data.
+ typedef std::set<DeviceData::Type>::const_iterator SetIterator;
+ for (SetIterator i = polling_data_types_.begin();
+ i != polling_data_types_.end(); ++i) {
+ DeviceData::Type device_data_type = *i;
+ scoped_refptr<const DeviceData> device_data(data_fetcher_->GetDeviceData(
+ device_data_type));
+
+ if (device_data == NULL) {
+ LOG(ERROR) << "Failed to poll device data fetcher.";
+ ScheduleDoNotify(NULL, device_data_type);
+ continue;
+ }
+
+ typedef std::map<DeviceData::Type, scoped_refptr<const DeviceData> >::
+ iterator Iterator;
+ Iterator iter = last_device_data_map_->find(device_data_type);
- ScheduleDoNotify(Orientation::Empty());
- return;
- }
+ if (iter != last_device_data_map_->end() &&
hans 2012/07/30 16:12:52 maybe a comment here would help? or maybe we don'
aousterh 2012/08/03 11:08:14 I did it that way because last_device_data_map_ wa
+ !device_data->ShouldFireEvent((*iter).second))
+ continue;
- if (!orientation.is_empty() &&
- SignificantlyDifferent(orientation, last_orientation_)) {
- last_orientation_ = orientation;
- ScheduleDoNotify(orientation);
+ // Update the last device data of this type and notify observers
hans 2012/07/30 16:12:52 nit: period.
aousterh 2012/08/03 11:08:14 Done.
+ if (device_data->ShouldFireEvent((*iter).second))
hans 2012/07/30 16:12:52 i'm confused by this and the two lines below.. don
aousterh 2012/08/03 11:08:14 Done.
+ last_device_data_map_->erase(iter);
+ last_device_data_map_->insert(std::pair<DeviceData::Type,
+ scoped_refptr<const DeviceData> >(device_data_type, device_data));
+ ScheduleDoNotify(device_data, device_data_type);
}
ScheduleDoPoll();
@@ -159,43 +231,6 @@ void ProviderImpl::ScheduleDoPoll() {
SamplingInterval());
}
-namespace {
-
-bool IsElementSignificantlyDifferent(bool can_provide_element1,
- bool can_provide_element2,
- double element1,
- double element2) {
- const double kThreshold = 0.1;
-
- if (can_provide_element1 != can_provide_element2)
- return true;
- if (can_provide_element1 &&
- std::fabs(element1 - element2) >= kThreshold)
- return true;
- return false;
-}
-} // namespace
-
-// Returns true if two orientations are considered different enough that
-// observers should be notified of the new orientation.
-bool ProviderImpl::SignificantlyDifferent(const Orientation& o1,
- const Orientation& o2) {
- return IsElementSignificantlyDifferent(o1.can_provide_alpha(),
- o2.can_provide_alpha(),
- o1.alpha(),
- o2.alpha()) ||
- IsElementSignificantlyDifferent(o1.can_provide_beta(),
- o2.can_provide_beta(),
- o1.beta(),
- o2.beta()) ||
- IsElementSignificantlyDifferent(o1.can_provide_gamma(),
- o2.can_provide_gamma(),
- o1.gamma(),
- o2.gamma()) ||
- (o1.can_provide_absolute() != o2.can_provide_absolute() ||
- o1.absolute() != o2.absolute());
-}
-
base::TimeDelta ProviderImpl::SamplingInterval() const {
DCHECK(MessageLoop::current() == polling_thread_->message_loop());
DCHECK(data_fetcher_.get());

Powered by Google App Engine
This is Rietveld 408576698