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

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: Small changes to appease try bots Created 8 years, 4 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 3118093585a95d95477bf0cf4a14c52865b0de1d..ae4088405621893241c9b8530e3fdbfd1b4ef0f7 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>
@@ -11,25 +12,9 @@
#include "base/message_loop.h"
#include "base/threading/thread.h"
#include "base/threading/worker_pool.h"
-#include "content/browser/device_orientation/orientation.h"
-#include "content/browser/device_orientation/provider_impl.h"
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;
-}
-
void DeleteThread(base::Thread* thread) {
thread->Stop();
delete thread;
@@ -46,8 +31,12 @@ class ProviderImpl::PollingThread : public base::Thread {
MessageLoop* creator_loop);
virtual ~PollingThread();
- // Method for finding a suitable DataFetcher and starting the polling.
- void Initialize(DataFetcherFactory factory);
+ // Method for creating a DataFetcher and starting the polling, if the fetcher
+ // can provide this type of data.
+ void Initialize(DataFetcherFactory factory, DeviceData::Type type);
+
+ // Method for adding a type of data to poll for.
+ void DoAddPollingDataType(DeviceData::Type type);
private:
// Method for polling a DataFetcher.
@@ -56,10 +45,8 @@ class ProviderImpl::PollingThread : public base::Thread {
// Schedule a notification to the |provider_| which lives on a different
// thread (|creator_loop_| is its message loop).
- void ScheduleDoNotify(const Orientation& orientation);
-
- static bool SignificantlyDifferent(const Orientation& orientation1,
- const Orientation& orientation2);
+ void ScheduleDoNotify(const DeviceData* device_data,
+ DeviceData::Type device_data_type);
enum { kDesiredSamplingIntervalMs = 100 };
base::TimeDelta SamplingInterval() const;
@@ -69,7 +56,9 @@ class ProviderImpl::PollingThread : public base::Thread {
MessageLoop* creator_loop_;
scoped_ptr<DataFetcher> data_fetcher_;
- Orientation last_orientation_;
+ std::map<DeviceData::Type, scoped_refptr<const DeviceData> >
+ last_device_data_map_;
+ std::set<DeviceData::Type> polling_data_types_;
base::WeakPtr<ProviderImpl> provider_;
};
@@ -86,56 +75,76 @@ ProviderImpl::PollingThread::PollingThread(
ProviderImpl::PollingThread::~PollingThread() {
}
-void ProviderImpl::PollingThread::Initialize(DataFetcherFactory factory) {
+void ProviderImpl::PollingThread::DoAddPollingDataType(DeviceData::Type type) {
+ DCHECK(MessageLoop::current() == message_loop());
+
+ polling_data_types_.insert(type);
+}
+
+void ProviderImpl::PollingThread::Initialize(DataFetcherFactory factory,
+ DeviceData::Type type) {
DCHECK(MessageLoop::current() == message_loop());
if (factory != NULL) {
- // Try to use factory to create a fetcher that can provide orientation data.
+ // Try to use factory to create a fetcher that can provide this type of
+ // data. If factory creates a fetcher that provides this type of data,
+ // start polling.
scoped_ptr<DataFetcher> fetcher(factory());
- Orientation orientation;
- if (fetcher.get() && fetcher->GetOrientation(&orientation)) {
- // Pass ownership of fetcher to provider_.
- data_fetcher_.swap(fetcher);
- last_orientation_ = orientation;
+ if (fetcher.get()) {
+ scoped_refptr<const DeviceData> device_data(fetcher->GetDeviceData(type));
+ if (device_data != NULL) {
+ // Pass ownership of fetcher to provider_.
+ data_fetcher_.swap(fetcher);
+ last_device_data_map_[type] = device_data;
- // Notify observers.
- if (!orientation.is_empty())
- ScheduleDoNotify(orientation);
+ // Notify observers.
+ ScheduleDoNotify(device_data, type);
- // Start polling.
- ScheduleDoPoll();
- return;
+ // Start polling.
+ ScheduleDoPoll();
+ return;
+ }
}
}
- // When no orientation data can be provided.
- ScheduleDoNotify(Orientation::Empty());
+ // When no device data can be provided.
+ ScheduleDoNotify(NULL, type);
}
void ProviderImpl::PollingThread::ScheduleDoNotify(
- const Orientation& orientation) {
+ const DeviceData* device_data, DeviceData::Type device_data_type) {
DCHECK(MessageLoop::current() == message_loop());
- creator_loop_->PostTask(
- FROM_HERE, base::Bind(&ProviderImpl::DoNotify, provider_, orientation));
+ creator_loop_->PostTask(FROM_HERE,
+ base::Bind(&ProviderImpl::DoNotify, provider_,
+ device_data, device_data_type));
}
void ProviderImpl::PollingThread::DoPoll() {
DCHECK(MessageLoop::current() == 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;
+ }
- ScheduleDoNotify(Orientation::Empty());
- return;
- }
+ const DeviceData* old_data = last_device_data_map_[device_data_type];
+ if (old_data != NULL && !device_data->ShouldFireEvent(old_data))
+ 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.
+ last_device_data_map_[device_data_type] = device_data;
+ ScheduleDoNotify(device_data, device_data_type);
}
ScheduleDoPoll();
@@ -150,27 +159,6 @@ void ProviderImpl::PollingThread::ScheduleDoPoll() {
SamplingInterval());
}
-// Returns true if two orientations are considered different enough that
-// observers should be notified of the new orientation.
-bool ProviderImpl::PollingThread::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::PollingThread::SamplingInterval() const {
DCHECK(MessageLoop::current() == message_loop());
DCHECK(data_fetcher_.get());
@@ -192,14 +180,32 @@ ProviderImpl::~ProviderImpl() {
Stop();
}
+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(&PollingThread::DoAddPollingDataType,
+ base::Unretained(polling_thread_),
+ type));
+}
+
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.
+ const DeviceData *last_notification = last_notifications_map_[type];
+ if (last_notification != NULL)
+ observer->OnDeviceDataUpdate(last_notification, type);
+ }
+
+ ScheduleDoAddPollingDataType(type);
}
void ProviderImpl::RemoveObserver(Observer* observer) {
@@ -210,20 +216,20 @@ void ProviderImpl::RemoveObserver(Observer* observer) {
Stop();
}
-void ProviderImpl::Start() {
+void ProviderImpl::Start(DeviceData::Type type) {
DCHECK(MessageLoop::current() == creator_loop_);
DCHECK(!polling_thread_);
- polling_thread_ = new PollingThread("Device orientation polling thread",
+ polling_thread_ = new PollingThread("Device data polling thread",
weak_factory_.GetWeakPtr(),
creator_loop_);
if (!polling_thread_->Start()) {
- LOG(ERROR) << "Failed to start device orientation polling thread";
+ LOG(ERROR) << "Failed to start device data polling thread";
delete polling_thread_;
polling_thread_ = NULL;
return;
}
- ScheduleInitializePollingThread();
+ ScheduleInitializePollingThread(type);
}
void ProviderImpl::Stop() {
@@ -241,30 +247,48 @@ void ProviderImpl::Stop() {
}
}
-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(&PollingThread::Initialize,
base::Unretained(polling_thread_),
- factory_));
+ factory_,
+ 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(); i != observers_.end(); ++i)
- (*i)->OnOrientationUpdate(orientation);
+ // Update last notification of this type.
+ 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();
}
}
+
} // namespace device_orientation
« no previous file with comments | « content/browser/device_orientation/provider_impl.h ('k') | content/browser/device_orientation/provider_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698