Commit 7701bcdb authored by aousterh@chromium.org's avatar aousterh@chromium.org

Refactors DeviceOrientation to make it more extensible

This refactors the ProviderImpl in DeviceOrientation to make it more general.
This will make it easy to add other types of device data (such as DeviceMotion)
in the future and to have them use the same Provider/ProviderImpl.

This is an alternative to http://codereview.chromium.org/10689106.

TBR=avi
BUG=none
TEST=browser_tests:DeviceOrientationBrowserTest.BasicTest,
content_unittests --gtest_filter=DeviceOrientation*


Review URL: https://chromiumcodereview.appspot.com/10755002

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@149864 0039d316-1c4b-4281-b951-d872f2087c98
parent c0e04e9c
......@@ -24,6 +24,12 @@ AccelerometerMac::~AccelerometerMac() {
AccelerometerMac::AccelerometerMac() {
}
const DeviceData* AccelerometerMac::GetDeviceData(DeviceData::Type type) {
if (type != DeviceData::kTypeOrientation)
return NULL;
return GetOrientation();
}
// Retrieve per-axis orientation values.
//
// Axes and angles are defined according to the W3C DeviceOrientation Draft.
......@@ -33,13 +39,13 @@ AccelerometerMac::AccelerometerMac() {
//
// Returns false in case of error.
//
bool AccelerometerMac::GetOrientation(Orientation* orientation) {
const Orientation* AccelerometerMac::GetOrientation() {
DCHECK(sudden_motion_sensor_.get());
// Retrieve per-axis calibrated values.
float axis_value[3];
if (!sudden_motion_sensor_->ReadSensorValues(axis_value))
return false;
return NULL;
// Transform the accelerometer values to W3C draft angles.
//
......@@ -63,6 +69,8 @@ bool AccelerometerMac::GetOrientation(Orientation* orientation) {
//
const double kRad2deg = 180.0 / M_PI;
scoped_refptr<Orientation> orientation(new Orientation());
orientation->set_beta(kRad2deg * atan2(-axis_value[1], axis_value[2]));
orientation->set_gamma(kRad2deg * asin(axis_value[0]));
// TODO(aousterh): should absolute_ be set to false here?
......@@ -85,7 +93,7 @@ bool AccelerometerMac::GetOrientation(Orientation* orientation) {
DCHECK_GE(orientation->gamma(), -90.0);
DCHECK_LT(orientation->gamma(), 90.0);
return true;
return orientation;
}
bool AccelerometerMac::Init() {
......
......@@ -10,23 +10,27 @@
#include "base/compiler_specific.h"
#include "base/memory/scoped_ptr.h"
#include "content/browser/device_orientation/data_fetcher.h"
#include "content/browser/device_orientation/device_data.h"
class SuddenMotionSensor;
namespace device_orientation {
class Orientation;
class AccelerometerMac : public DataFetcher {
public:
static DataFetcher* Create();
// Implement DataFetcher.
virtual bool GetOrientation(Orientation* orientation) OVERRIDE;
virtual const DeviceData* GetDeviceData(DeviceData::Type type) OVERRIDE;
virtual ~AccelerometerMac();
private:
AccelerometerMac();
bool Init();
const Orientation* GetOrientation();
scoped_ptr<SuddenMotionSensor> sudden_motion_sensor_;
};
......
......@@ -5,18 +5,18 @@
#ifndef CONTENT_BROWSER_DEVICE_ORIENTATION_DATA_FETCHER_H_
#define CONTENT_BROWSER_DEVICE_ORIENTATION_DATA_FETCHER_H_
namespace device_orientation {
#include "content/browser/device_orientation/device_data.h"
class Orientation;
namespace device_orientation {
class DataFetcher {
public:
virtual ~DataFetcher() {}
// Returns false if there was a fatal error getting the orientation.
// Returns true otherwise. If the fetcher has orientation data available
// it will fill it in, otherwise the argument will be unaltered.
virtual bool GetOrientation(Orientation*) = 0;
// Returns NULL if there was a fatal error getting the device data of this
// type or if this fetcher can never provide this type of data. Otherwise,
// returns a pointer to a DeviceData containing the most recent data.
virtual const DeviceData* GetDeviceData(DeviceData::Type type) = 0;
};
} // namespace device_orientation
......
......@@ -54,7 +54,14 @@ DataFetcherImplAndroid::~DataFetcherImplAndroid() {
Stop();
}
bool DataFetcherImplAndroid::GetOrientation(Orientation* orientation) {
const DeviceData* DataFetcherImplAndroid::GetDeviceData(
DeviceData::Type type) {
if (type != DeviceData::kTypeOrientation)
return NULL;
return GetOrientation();
}
const Orientation* DataFetcherImplAndroid::GetOrientation() {
// Do we have a new orientation value? (It's safe to do this outside the lock
// because we only skip the lock if the value is null. We always enter the
// lock if we're going to make use of the new value.)
......@@ -62,9 +69,9 @@ bool DataFetcherImplAndroid::GetOrientation(Orientation* orientation) {
base::AutoLock autolock(next_orientation_lock_);
next_orientation_.swap(current_orientation_);
}
if (current_orientation_.get())
*orientation = *current_orientation_;
return true;
if (!current_orientation_.get())
return new Orientation();
return current_orientation_.get();
}
void DataFetcherImplAndroid::GotOrientation(
......@@ -76,7 +83,7 @@ void DataFetcherImplAndroid::GotOrientation(
orientation->set_beta(beta);
orientation->set_gamma(gamma);
orientation->set_absolute(true);
next_orientation_.reset(orientation);
next_orientation_ = orientation;
}
bool DataFetcherImplAndroid::Start(int rate_in_milliseconds) {
......
......@@ -10,17 +10,19 @@
#include "base/memory/scoped_ptr.h"
#include "base/synchronization/lock.h"
#include "content/browser/device_orientation/data_fetcher.h"
#include "content/browser/device_orientation/orientation.h"
#include "content/browser/device_orientation/device_data.h"
namespace device_orientation {
class Orientation;
// Android implementation of DeviceOrientation API.
// Android's SensorManager has a push API, whereas Chrome wants to pull data.
// To fit them together, we store incoming sensor events in a 1-element buffer.
// SensorManager calls SetOrientation() which pushes a new value (discarding the
// previous value if any). Chrome calls GetOrientation() which reads the most
// recent value. Repeated calls to GetOrientation() will return the same value.
// previous value if any). Chrome calls GetDeviceData() which reads the most
// recent value. Repeated calls to GetDeviceData() will return the same value.
class DataFetcherImplAndroid : public DataFetcher {
public:
......@@ -38,21 +40,22 @@ class DataFetcherImplAndroid : public DataFetcher {
double alpha, double beta, double gamma);
// Implementation of DataFetcher.
virtual bool GetOrientation(Orientation* orientation) OVERRIDE;
virtual const DeviceData* GetDeviceData(DeviceData::Type type) OVERRIDE;
private:
DataFetcherImplAndroid();
const Orientation* GetOrientation();
// Wrappers for JNI methods.
bool Start(int rate_in_milliseconds);
void Stop();
// Value returned by GetOrientation.
scoped_ptr<Orientation> current_orientation_;
// Value returned by GetDeviceData.
scoped_refptr<Orientation> current_orientation_;
// 1-element buffer, written by GotOrientation, read by GetOrientation.
// 1-element buffer, written by GotOrientation, read by GetDeviceData.
base::Lock next_orientation_lock_;
scoped_ptr<Orientation> next_orientation_;
scoped_refptr<Orientation> next_orientation_;
DISALLOW_COPY_AND_ASSIGN(DataFetcherImplAndroid);
};
......
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CONTENT_BROWSER_DEVICE_ORIENTATION_DEVICE_DATA_H_
#define CONTENT_BROWSER_DEVICE_ORIENTATION_DEVICE_DATA_H_
#include "base/memory/ref_counted.h"
#include "content/common/content_export.h"
namespace IPC {
class Message;
}
namespace device_orientation {
class CONTENT_EXPORT DeviceData :
public base::RefCountedThreadSafe<DeviceData> {
public:
enum Type {
kTypeOrientation,
kTypeTest
};
virtual IPC::Message* CreateIPCMessage(int render_view_id) const = 0;
virtual bool ShouldFireEvent(const DeviceData* other) const = 0;
protected:
DeviceData() {}
virtual ~DeviceData() {}
private:
friend class base::RefCountedThreadSafe<DeviceData>;
DISALLOW_COPY_AND_ASSIGN(DeviceData);
};
} // namespace device_orientation
#endif // CONTENT_BROWSER_DEVICE_ORIENTATION_DEVICE_DATA_H_
......@@ -5,6 +5,8 @@
#include "base/command_line.h"
#include "base/file_path.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "content/browser/device_orientation/device_data.h"
#include "content/browser/device_orientation/orientation.h"
#include "content/browser/device_orientation/provider.h"
#include "content/public/browser/web_contents.h"
......@@ -17,20 +19,23 @@ namespace device_orientation {
class MockProvider : public Provider {
public:
explicit MockProvider(const Orientation& orientation)
: orientation_(orientation),
MockProvider(const DeviceData* device_data, DeviceData::Type type)
: device_data_(device_data),
device_data_type_(type),
added_observer_(false),
removed_observer_(false) {}
removed_observer_(false) {
}
virtual void AddObserver(Observer* observer) {
added_observer_ = true;
observer->OnOrientationUpdate(orientation_);
observer->OnDeviceDataUpdate(device_data_.get(), device_data_type_);
}
virtual void RemoveObserver(Observer* observer) {
removed_observer_ = true;
}
Orientation orientation_;
scoped_refptr<const DeviceData> device_data_;
DeviceData::Type device_data_type_;
bool added_observer_;
bool removed_observer_;
......@@ -48,12 +53,13 @@ class DeviceOrientationBrowserTest : public content::ContentBrowserTest {
// crbug.com/113952
IN_PROC_BROWSER_TEST_F(DeviceOrientationBrowserTest, BasicTest) {
Orientation test_orientation;
test_orientation.set_alpha(1);
test_orientation.set_beta(2);
test_orientation.set_gamma(3);
test_orientation.set_absolute(true);
scoped_refptr<MockProvider> provider(new MockProvider(test_orientation));
scoped_refptr<Orientation> test_orientation(new Orientation());
test_orientation->set_alpha(1);
test_orientation->set_beta(2);
test_orientation->set_gamma(3);
test_orientation->set_absolute(true);
scoped_refptr<MockProvider> provider(new MockProvider(
test_orientation, DeviceData::kTypeOrientation));
Provider::SetInstanceForTests(provider.get());
// The test page will register an event handler for orientation events,
......
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "content/browser/device_orientation/message_filter.h"
#include "content/browser/device_orientation/observer_delegate.h"
#include "content/browser/device_orientation/provider.h"
#include "content/public/browser/browser_thread.h"
using content::BrowserThread;
namespace device_orientation {
MessageFilter::MessageFilter(DeviceData::Type device_data_type)
: provider_(NULL),
device_data_type_(device_data_type) {
}
MessageFilter::~MessageFilter() {
}
void MessageFilter::OnStartUpdating(int render_view_id) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
if (!provider_)
provider_ = Provider::GetInstance();
observers_map_[render_view_id] = new ObserverDelegate(device_data_type_,
provider_, render_view_id, this);
}
void MessageFilter::OnStopUpdating(int render_view_id) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
observers_map_.erase(render_view_id);
}
} // namespace device_orientation
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CONTENT_BROWSER_DEVICE_ORIENTATION_MESSAGE_FILTER_H_
#define CONTENT_BROWSER_DEVICE_ORIENTATION_MESSAGE_FILTER_H_
#include <map>
#include "content/browser/device_orientation/device_data.h"
#include "content/public/browser/browser_message_filter.h"
namespace device_orientation {
// Helper class that observes a Provider and forwards updates to a RenderView.
class ObserverDelegate;
class Provider;
class MessageFilter : public content::BrowserMessageFilter {
public:
// content::BrowserMessageFilter implementation.
virtual bool OnMessageReceived(const IPC::Message& message,
bool* message_was_ok) OVERRIDE = 0;
protected:
MessageFilter(DeviceData::Type device_data_type);
virtual ~MessageFilter();
void OnStartUpdating(int render_view_id);
void OnStopUpdating(int render_view_id);
private:
// map from render_view_id to ObserverDelegate.
std::map<int, scoped_refptr<ObserverDelegate> > observers_map_;
scoped_refptr<Provider> provider_;
DeviceData::Type device_data_type_;
};
} // namespace device_orientation
#endif // CONTENT_BROWSER_DEVICE_ORIENTATION_MESSAGE_FILTER_H_
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "content/browser/device_orientation/observer_delegate.h"
#include "base/logging.h"
#include "content/browser/device_orientation/device_data.h"
#include "content/browser/device_orientation/orientation.h"
#include "ipc/ipc_sender.h"
namespace device_orientation {
ObserverDelegate::ObserverDelegate(DeviceData::Type device_data_type,
Provider* provider, int render_view_id,
IPC::Sender* sender)
: Observer(device_data_type),
provider_(provider),
render_view_id_(render_view_id),
sender_(sender) {
provider_->AddObserver(this);
}
ObserverDelegate::~ObserverDelegate() {
provider_->RemoveObserver(this);
}
void ObserverDelegate::OnDeviceDataUpdate(
const DeviceData* device_data, DeviceData::Type device_data_type) {
scoped_refptr<const DeviceData> new_device_data(device_data);
if (!new_device_data.get())
new_device_data = EmptyDeviceData(device_data_type);
sender_->Send(new_device_data->CreateIPCMessage(render_view_id_));
}
DeviceData* ObserverDelegate::EmptyDeviceData(DeviceData::Type type) {
DCHECK(type == DeviceData::kTypeOrientation);
return new Orientation();
}
} // namespace device_orientation
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CONTENT_BROWSER_DEVICE_ORIENTATION_OBSERVER_DELEGATE_H_
#define CONTENT_BROWSER_DEVICE_ORIENTATION_OBSERVER_DELEGATE_H_
#include "content/browser/device_orientation/device_data.h"
#include "content/browser/device_orientation/provider.h"
namespace IPC {
class Sender;
}
namespace device_orientation {
class ObserverDelegate
: public base::RefCounted<ObserverDelegate>, public Provider::Observer {
public:
// Create ObserverDelegate that observes provider and forwards updates to
// render_view_id.
// Will stop observing provider when destructed.
ObserverDelegate(DeviceData::Type device_data_type, Provider* provider,
int render_view_id, IPC::Sender* sender);
// From Provider::Observer.
virtual void OnDeviceDataUpdate(const DeviceData* device_data,
DeviceData::Type device_data_type) OVERRIDE;
private:
static DeviceData* EmptyDeviceData(DeviceData::Type type);
friend class base::RefCounted<ObserverDelegate>;
virtual ~ObserverDelegate();
scoped_refptr<Provider> provider_;
int render_view_id_;
IPC::Sender* sender_; // Weak pointer.
DISALLOW_COPY_AND_ASSIGN(ObserverDelegate);
};
} // namespace device_orientation
#endif // CONTENT_BROWSER_DEVICE_ORIENTATION_OBSERVER_DELEGATE_H_
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "content/browser/device_orientation/orientation.h"
#include <cmath>
#include "content/common/device_orientation_messages.h"
namespace device_orientation {
Orientation::Orientation()
: can_provide_alpha_(false),
can_provide_beta_(false),
can_provide_gamma_(false),
can_provide_absolute_(false) {
}
Orientation::~Orientation() {
}
IPC::Message* Orientation::CreateIPCMessage(int render_view_id) const {
DeviceOrientationMsg_Updated_Params params;
params.can_provide_alpha = can_provide_alpha_;
params.alpha = alpha_;
params.can_provide_beta = can_provide_beta_;
params.beta = beta_;
params.can_provide_gamma = can_provide_gamma_;
params.gamma = gamma_;
params.can_provide_absolute = can_provide_absolute_;
params.absolute = absolute_;
return new DeviceOrientationMsg_Updated(render_view_id, params);
}
// Returns true if two orientations are considered different enough that
// observers should be notified of the new orientation.
bool Orientation::ShouldFireEvent(const DeviceData* old_data) const {
scoped_refptr<const Orientation> old_orientation(
static_cast<const Orientation*>(old_data));
return IsElementSignificantlyDifferent(can_provide_alpha_,
old_orientation->can_provide_alpha(),
alpha_,
old_orientation->alpha()) ||
IsElementSignificantlyDifferent(can_provide_beta_,
old_orientation->can_provide_beta(),
beta_,
old_orientation->beta()) ||
IsElementSignificantlyDifferent(can_provide_gamma_,
old_orientation->can_provide_gamma(),
gamma_,
old_orientation->gamma()) ||
can_provide_absolute_ != old_orientation->can_provide_absolute() ||
absolute_ != old_orientation->absolute();
}
bool Orientation::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 device_orientation
......@@ -5,52 +5,24 @@
#ifndef CONTENT_BROWSER_DEVICE_ORIENTATION_ORIENTATION_H_
#define CONTENT_BROWSER_DEVICE_ORIENTATION_ORIENTATION_H_
#include "base/compiler_specific.h"
#include "content/browser/device_orientation/device_data.h"
#include "content/common/content_export.h"
namespace device_orientation {
class Orientation {
class Orientation : public DeviceData {
public:
// alpha, beta, gamma and absolute are the rotations around the axes as
// specified in http://dev.w3.org/geo/api/spec-source-orientation.html
//
// can_provide_{alpha,beta,gamma,absolute} is true if data can be provided
// for that variable.
CONTENT_EXPORT Orientation();
Orientation()
: alpha_(0),
beta_(0),
gamma_(0),
absolute_(false),
can_provide_alpha_(false),
can_provide_beta_(false),
can_provide_gamma_(false),
can_provide_absolute_(false) {
}
Orientation(const Orientation& orientation)
: alpha_(orientation.alpha()),
beta_(orientation.beta()),
gamma_(orientation.gamma()),
absolute_(orientation.absolute()),
can_provide_alpha_(orientation.can_provide_alpha()),
can_provide_beta_(orientation.can_provide_beta()),
can_provide_gamma_(orientation.can_provide_gamma()),
can_provide_absolute_(orientation.can_provide_absolute()) {
}
void operator=(const Orientation& source) {
alpha_ = source.alpha();
beta_ = source.beta();
gamma_ = source.gamma();
absolute_ = source.absolute();
can_provide_alpha_ = source.can_provide_alpha();
can_provide_beta_ = source.can_provide_beta();
can_provide_gamma_ = source.can_provide_gamma();
can_provide_absolute_ = source.can_provide_absolute();
}
static Orientation Empty() { return Orientation(); }
bool is_empty() const {
return !can_provide_alpha_ && !can_provide_beta_ && !can_provide_gamma_
&& !can_provide_absolute_;
}
// From DeviceData.
virtual IPC::Message* CreateIPCMessage(int render_view_id) const OVERRIDE;
virtual bool ShouldFireEvent(const DeviceData* old_data) const OVERRIDE;
void set_alpha(double alpha) {
can_provide_alpha_ = true;
......@@ -81,6 +53,11 @@ class Orientation {
bool absolute() const { return absolute_; }
private:
virtual ~Orientation();
static bool IsElementSignificantlyDifferent(bool can_provide_element1,
bool can_provide_element2, double element1, double element2);
double alpha_;
double beta_;
double gamma_;
......
......@@ -4,10 +4,7 @@
#include "content/browser/device_orientation/orientation_message_filter.h"
#include "base/memory/scoped_ptr.h"
#include "content/browser/device_orientation/orientation.h"
#include "content/browser/device_orientation/provider.h"
#include "content/browser/renderer_host/render_view_host_impl.h"
#include "content/browser/device_orientation/device_data.h"
#include "content/common/device_orientation_messages.h"
#include "content/public/browser/browser_thread.h"
......@@ -15,66 +12,15 @@ using content::BrowserThread;
namespace device_orientation {
OrientationMessageFilter::OrientationMessageFilter() : provider_(NULL) {
OrientationMessageFilter::OrientationMessageFilter()
: MessageFilter(DeviceData::kTypeOrientation) {
}
OrientationMessageFilter::~OrientationMessageFilter() {
}
class OrientationMessageFilter::ObserverDelegate
: public base::RefCounted<ObserverDelegate>, public Provider::Observer {
public:
// Create ObserverDelegate that observes provider and forwards updates to
// render_view_id in process_id.
// Will stop observing provider when destructed.
ObserverDelegate(Provider* provider,
int render_view_id,
IPC::Sender* sender);
// From Provider::Observer.
virtual void OnOrientationUpdate(const Orientation& orientation);
private:
friend class base::RefCounted<ObserverDelegate>;
virtual ~ObserverDelegate();
scoped_refptr<Provider> provider_;
int render_view_id_;
IPC::Sender* sender_; // Weak pointer.
DISALLOW_COPY_AND_ASSIGN(ObserverDelegate);
};
OrientationMessageFilter::ObserverDelegate::ObserverDelegate(Provider* provider,
int render_view_id,
IPC::Sender* sender)
: provider_(provider),
render_view_id_(render_view_id),
sender_(sender) {
provider_->AddObserver(this);
}
OrientationMessageFilter::ObserverDelegate::~ObserverDelegate() {
provider_->RemoveObserver(this);
}
void OrientationMessageFilter::ObserverDelegate::OnOrientationUpdate(
const Orientation& orientation) {
DeviceOrientationMsg_Updated_Params params;
params.can_provide_alpha = orientation.can_provide_alpha();
params.alpha = orientation.alpha();
params.can_provide_beta = orientation.can_provide_beta();
params.beta = orientation.beta();
params.can_provide_gamma = orientation.can_provide_gamma();
params.gamma = orientation.gamma();
params.can_provide_absolute = orientation.can_provide_absolute();
params.absolute = orientation.absolute();
sender_->Send(new DeviceOrientationMsg_Updated(render_view_id_, params));
}
bool OrientationMessageFilter::OnMessageReceived(const IPC::Message& message,
bool* message_was_ok) {
bool* message_was_ok) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
bool handled = true;
IPC_BEGIN_MESSAGE_MAP_EX(OrientationMessageFilter, message, *message_was_ok)
......@@ -85,21 +31,4 @@ bool OrientationMessageFilter::OnMessageReceived(const IPC::Message& message,
return handled;
}
void OrientationMessageFilter::OnStartUpdating(int render_view_id) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
if (!provider_)
provider_ = Provider::GetInstance();
observers_map_[render_view_id] = new ObserverDelegate(provider_,
render_view_id,
this);
}
void OrientationMessageFilter::OnStopUpdating(int render_view_id) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
observers_map_.erase(render_view_id);
}
} // namespace device_orientation
......@@ -7,12 +7,11 @@
#include <map>
#include "content/browser/device_orientation/provider.h"
#include "content/public/browser/browser_message_filter.h"
#include "content/browser/device_orientation/message_filter.h"
namespace device_orientation {
class OrientationMessageFilter : public content::BrowserMessageFilter {
class OrientationMessageFilter : public MessageFilter {
public:
OrientationMessageFilter();
......@@ -23,17 +22,6 @@ class OrientationMessageFilter : public content::BrowserMessageFilter {
private:
virtual ~OrientationMessageFilter();
void OnStartUpdating(int render_view_id);
void OnStopUpdating(int render_view_id);
// Helper class that observes a Provider and forwards updates to a RenderView.
class ObserverDelegate;
// map from render_view_id to ObserverDelegate.
std::map<int, scoped_refptr<ObserverDelegate> > observers_map_;
scoped_refptr<Provider> provider_;
DISALLOW_COPY_AND_ASSIGN(OrientationMessageFilter);
};
......
......@@ -6,23 +6,31 @@
#define CONTENT_BROWSER_DEVICE_ORIENTATION_PROVIDER_H_
#include "base/memory/ref_counted.h"
#include "content/browser/device_orientation/device_data.h"
#include "content/common/content_export.h"
namespace device_orientation {
class Orientation;
class CONTENT_EXPORT Provider : public base::RefCountedThreadSafe<Provider> {
public:
class Observer {
public:
// Called when the orientation changes.
// Called when device data changes.
// An Observer must not synchronously call Provider::RemoveObserver
// or Provider::AddObserver when this is called.
virtual void OnOrientationUpdate(const Orientation& orientation) = 0;
virtual void OnDeviceDataUpdate(const DeviceData* device_data,
DeviceData::Type device_data_type) = 0;
DeviceData::Type device_data_type() { return device_data_type_; }
protected:
Observer(DeviceData::Type device_data_type)
: device_data_type_(device_data_type) {
}
virtual ~Observer() {}
private:
// Each Observer observes exactly one type of DeviceData.
DeviceData::Type device_data_type_;
};
// Returns a pointer to the singleton instance of this class.
......@@ -39,8 +47,7 @@ class CONTENT_EXPORT Provider : public base::RefCountedThreadSafe<Provider> {
// Get the current instance. Used for testing.
static Provider* GetInstanceForTests();
// Note: AddObserver may call back synchronously to the observer with
// orientation data.
// Note: AddObserver may call back synchronously to the observer with data.
virtual void AddObserver(Observer* observer) = 0;
virtual void RemoveObserver(Observer* observer) = 0;
......
......@@ -5,6 +5,7 @@
#ifndef CONTENT_BROWSER_DEVICE_ORIENTATION_PROVIDER_IMPL_H_
#define CONTENT_BROWSER_DEVICE_ORIENTATION_PROVIDER_IMPL_H_
#include <map>
#include <set>
#include <vector>
......@@ -12,7 +13,7 @@
#include "base/memory/weak_ptr.h"
#include "base/time.h"
#include "content/browser/device_orientation/data_fetcher.h"
#include "content/browser/device_orientation/orientation.h"
#include "content/browser/device_orientation/device_data.h"
#include "content/browser/device_orientation/provider.h"
#include "content/common/content_export.h"
......@@ -25,8 +26,8 @@ class ProviderImpl : public Provider {
typedef DataFetcher* (*DataFetcherFactory)();
// Create a ProviderImpl that uses the factory to create a DataFetcher that
// can provide orientation data. A NULL DataFetcherFactory indicates that
// there are no DataFetchers for this OS.
// can provide data. A NULL DataFetcherFactory indicates that there are no
// DataFetchers for this OS.
CONTENT_EXPORT ProviderImpl(DataFetcherFactory factory);
// From Provider.
......@@ -39,14 +40,19 @@ class ProviderImpl : public Provider {
virtual ~ProviderImpl();
// Starts or Stops the provider. Called from creator_loop_.
void Start();
void Start(DeviceData::Type type);
void Stop();
void ScheduleInitializePollingThread();
void ScheduleInitializePollingThread(DeviceData::Type device_data_type);
void ScheduleDoAddPollingDataType(DeviceData::Type type);
// Method for notifying observers of an orientation update.
// Method for notifying observers of a data update.
// Runs on the creator_thread_.
void DoNotify(const Orientation& orientation);
void DoNotify(const DeviceData* device_data,
DeviceData::Type device_data_type);
static bool ShouldFireEvent(const DeviceData* old_data,
const DeviceData* new_data, DeviceData::Type device_data_type);
// The Message Loop on which this object was created.
// Typically the I/O loop, but may be something else during testing.
......@@ -55,8 +61,11 @@ class ProviderImpl : public Provider {
// Members below are only to be used from the creator_loop_.
DataFetcherFactory factory_;
std::set<Observer*> observers_;
Orientation last_notification_;
std::map<DeviceData::Type, scoped_refptr<const DeviceData> >
last_notifications_map_;
// When polling_thread_ is running, members below are only to be used
// from that thread.
base::WeakPtrFactory<ProviderImpl> weak_factory_;
// Polling is done on this background thread. PollingThread is owned by
......
......@@ -281,9 +281,15 @@
'browser/device_orientation/data_fetcher.h',
'browser/device_orientation/data_fetcher_impl_android.cc',
'browser/device_orientation/data_fetcher_impl_android.h',
'browser/device_orientation/orientation.h',
'browser/device_orientation/device_data.h',
'browser/device_orientation/message_filter.cc',
'browser/device_orientation/message_filter.h',
'browser/device_orientation/observer_delegate.cc',
'browser/device_orientation/observer_delegate.h',
'browser/device_orientation/orientation_message_filter.cc',
'browser/device_orientation/orientation_message_filter.h',
'browser/device_orientation/orientation.cc',
'browser/device_orientation/orientation.h',
'browser/device_orientation/provider.cc',
'browser/device_orientation/provider.h',
'browser/device_orientation/provider_impl.cc',
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment