diff options
author | hans@chromium.org <hans@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-08-11 14:42:53 +0000 |
---|---|---|
committer | hans@chromium.org <hans@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-08-11 14:42:53 +0000 |
commit | 57ead35546411f3cb76705c0f21ef139593f5ec8 (patch) | |
tree | 4411a4b3db58b14eb0f3e852550ee73dabc9e273 /chrome | |
parent | bacfe81c2a05ea03178d6764f39b49bee66237de (diff) | |
download | chromium_src-57ead35546411f3cb76705c0f21ef139593f5ec8.zip chromium_src-57ead35546411f3cb76705c0f21ef139593f5ec8.tar.gz chromium_src-57ead35546411f3cb76705c0f21ef139593f5ec8.tar.bz2 |
Chromium plumbing for Device Orientation.
Add the plumbing needed for communicating with the Device Orientation code in WebKit.
RenderView provides an implementation of WebKit::WebDeviceOrientationClient: DeviceOrientationDispatcher. This communicates with the browser-side class device_orientation::DispatcherHost.
device_orientation::Provider, responsible for providing the orientation data, is just an empty shell for now.
BUG=44654
TEST=browser_tests --gtest_filter=DeviceOrientationBrowserTest.BasicTest
Review URL: http://codereview.chromium.org/2858049
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@55724 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
18 files changed, 568 insertions, 4 deletions
diff --git a/chrome/browser/device_orientation/device_orientation_browsertest.cc b/chrome/browser/device_orientation/device_orientation_browsertest.cc new file mode 100644 index 0000000..332316e --- /dev/null +++ b/chrome/browser/device_orientation/device_orientation_browsertest.cc @@ -0,0 +1,70 @@ +// Copyright (c) 2010 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 "base/command_line.h" +#include "base/file_path.h" +#include "base/ref_counted.h" +#include "chrome/browser/browser.h" +#include "chrome/browser/device_orientation/orientation.h" +#include "chrome/browser/device_orientation/provider.h" +#include "chrome/browser/tab_contents/tab_contents.h" +#include "chrome/common/chrome_switches.h" +#include "chrome/test/in_process_browser_test.h" +#include "chrome/test/ui_test_utils.h" + +namespace device_orientation { + +class MockProvider : public Provider { + public: + explicit MockProvider(const Orientation& orientation) + : orientation_(orientation), + added_observer_(false), + removed_observer_(false) {} + + virtual void AddObserver(Observer* observer) { + added_observer_ = true; + observer->OnOrientationUpdate(orientation_); + } + virtual void RemoveObserver(Observer* observer) { + removed_observer_ = true; + } + Orientation orientation_; + bool added_observer_; + bool removed_observer_; +}; + +class DeviceOrientationBrowserTest : public InProcessBrowserTest { + public: + // From InProcessBrowserTest. + virtual void SetUpCommandLine(CommandLine* command_line) { + command_line->AppendSwitch(switches::kEnableDeviceOrientation); + } + + GURL testUrl(const FilePath::CharType* filename) { + const FilePath kTestDir(FILE_PATH_LITERAL("device_orientation")); + return ui_test_utils::GetTestUrl(kTestDir, FilePath(filename)); + } +}; + +IN_PROC_BROWSER_TEST_F(DeviceOrientationBrowserTest, BasicTest) { + const Orientation kTestOrientation(true, 1, true, 2, true, 3); + scoped_refptr<MockProvider> provider = new MockProvider(kTestOrientation); + Provider::SetInstanceForTests(provider.get()); + + // The test page will register an event handler for orientation events, + // expects to get an event with kTestOrientation orientation, + // then removes the event handler and navigates to #pass. + GURL test_url = testUrl(FILE_PATH_LITERAL("device_orientation_test.html")); + ui_test_utils::NavigateToURLBlockUntilNavigationsComplete(browser(), + test_url, + 2); + + // Check that the page got the event it expected and that the provider + // saw requests for adding and removing an observer. + EXPECT_EQ("pass", browser()->GetSelectedTabContents()->GetURL().ref()); + EXPECT_TRUE(provider->added_observer_); + EXPECT_TRUE(provider->removed_observer_); +} + +} // namespace device_orientation diff --git a/chrome/browser/device_orientation/dispatcher_host.cc b/chrome/browser/device_orientation/dispatcher_host.cc new file mode 100644 index 0000000..605dc82 --- /dev/null +++ b/chrome/browser/device_orientation/dispatcher_host.cc @@ -0,0 +1,80 @@ +// Copyright (c) 2010 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 "chrome/browser/device_orientation/dispatcher_host.h" + +#include "base/scoped_ptr.h" +#include "chrome/browser/chrome_thread.h" +#include "chrome/browser/device_orientation/orientation.h" +#include "chrome/browser/device_orientation/provider.h" +#include "chrome/browser/renderer_host/render_view_host.h" +#include "chrome/browser/renderer_host/render_view_host_notification_task.h" +#include "chrome/common/chrome_switches.h" +#include "chrome/common/render_messages.h" +#include "ipc/ipc_message.h" + +namespace device_orientation { + +DispatcherHost::DispatcherHost(int process_id) + : process_id_(process_id) { +} + +DispatcherHost::~DispatcherHost() { + if (provider_) + provider_->RemoveObserver(this); +} + +bool DispatcherHost::OnMessageReceived(const IPC::Message& msg, + bool* msg_was_ok) { + DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO)); + bool handled = true; + IPC_BEGIN_MESSAGE_MAP_EX(DispatcherHost, msg, *msg_was_ok) + IPC_MESSAGE_HANDLER(ViewHostMsg_DeviceOrientation_StartUpdating, + OnStartUpdating) + IPC_MESSAGE_HANDLER(ViewHostMsg_DeviceOrientation_StopUpdating, + OnStopUpdating) + IPC_MESSAGE_UNHANDLED(handled = false) + IPC_END_MESSAGE_MAP() + return handled; +} + +void DispatcherHost::OnOrientationUpdate(const Orientation& orientation) { + ViewMsg_DeviceOrientationUpdated_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_; + + typedef std::set<int>::const_iterator Iterator; + for (Iterator i = render_view_ids_.begin(), e = render_view_ids_.end(); + i != e; ++i) { + IPC::Message* message = new ViewMsg_DeviceOrientationUpdated(*i, params); + CallRenderViewHost(process_id_, *i, &RenderViewHost::Send, message); + } +} + +void DispatcherHost::OnStartUpdating(int render_view_id) { + DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO)); + + render_view_ids_.insert(render_view_id); + if (render_view_ids_.size() == 1) { + DCHECK(!provider_); + provider_ = Provider::GetInstance(); + provider_->AddObserver(this); + } +} + +void DispatcherHost::OnStopUpdating(int render_view_id) { + DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO)); + + render_view_ids_.erase(render_view_id); + if (render_view_ids_.empty()) { + provider_->RemoveObserver(this); + provider_ = NULL; + } +} + +} // namespace device_orientation diff --git a/chrome/browser/device_orientation/dispatcher_host.h b/chrome/browser/device_orientation/dispatcher_host.h new file mode 100644 index 0000000..f43a68b --- /dev/null +++ b/chrome/browser/device_orientation/dispatcher_host.h @@ -0,0 +1,44 @@ +// Copyright (c) 2010 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 CHROME_BROWSER_DEVICE_ORIENTATION_DISPATCHER_HOST_H_ +#define CHROME_BROWSER_DEVICE_ORIENTATION_DISPATCHER_HOST_H_ + +#include <set> + +#include "base/ref_counted.h" +#include "chrome/browser/device_orientation/provider.h" + +namespace IPC { class Message; } + +namespace device_orientation { + +class Orientation; + +class DispatcherHost : public base::RefCountedThreadSafe<DispatcherHost>, + public Provider::Observer { + public: + explicit DispatcherHost(int process_id); + bool OnMessageReceived(const IPC::Message& msg, bool* msg_was_ok); + + // From Provider::Observer. + virtual void OnOrientationUpdate(const Orientation& orientation); + + private: + virtual ~DispatcherHost(); + friend class base::RefCountedThreadSafe<DispatcherHost>; + + void OnStartUpdating(int render_view_id); + void OnStopUpdating(int render_view_id); + + int process_id_; + std::set<int> render_view_ids_; + scoped_refptr<Provider> provider_; + + DISALLOW_COPY_AND_ASSIGN(DispatcherHost); +}; + +} // namespace device_orientation + +#endif // CHROME_BROWSER_DEVICE_ORIENTATION_DISPATCHER_HOST_H_ diff --git a/chrome/browser/device_orientation/orientation.h b/chrome/browser/device_orientation/orientation.h new file mode 100644 index 0000000..d43a989 --- /dev/null +++ b/chrome/browser/device_orientation/orientation.h @@ -0,0 +1,47 @@ +// Copyright (c) 2010 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 CHROME_BROWSER_DEVICE_ORIENTATION_ORIENTATION_H_ +#define CHROME_BROWSER_DEVICE_ORIENTATION_ORIENTATION_H_ + +namespace device_orientation { +class Orientation { + public: + // alpha, beta and gamma are the rotations around the axes as specified in + // http://dev.w3.org/geo/api/spec-source-orientation.html + // + // can_provide_{alpha,beta,gamma} is true if data can be provided for that + // variable. + + Orientation(bool can_provide_alpha, double alpha, + bool can_provide_beta, double beta, + bool can_provide_gamma, double gamma) + : alpha_(alpha), + beta_(beta), + gamma_(gamma), + can_provide_alpha_(can_provide_alpha), + can_provide_beta_(can_provide_beta), + can_provide_gamma_(can_provide_gamma) { + } + + Orientation() + : alpha_(0), + beta_(0), + gamma_(0), + can_provide_alpha_(false), + can_provide_beta_(false), + can_provide_gamma_(false) { + } + + double alpha_; + double beta_; + double gamma_; + bool can_provide_alpha_; + bool can_provide_beta_; + bool can_provide_gamma_; +}; + +} // namespace device_orientation + +#endif // CHROME_BROWSER_DEVICE_ORIENTATION_ORIENTATION_H_ diff --git a/chrome/browser/device_orientation/provider.cc b/chrome/browser/device_orientation/provider.cc new file mode 100644 index 0000000..16b24b3 --- /dev/null +++ b/chrome/browser/device_orientation/provider.cc @@ -0,0 +1,24 @@ +// Copyright (c) 2010 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 "chrome/browser/device_orientation/provider.h" + +namespace device_orientation { + +Provider* Provider::GetInstance() { + if (!instance_) + // TODO(hans) This is not finished. We will create an instance of the real + // Provider implementation once it is implemented. + instance_ = new Provider(); + return instance_; +} + +void Provider::SetInstanceForTests(Provider* provider) { + DCHECK(!instance_); + instance_ = provider; +} + +Provider* Provider::instance_ = NULL; + +} // namespace device_orientation diff --git a/chrome/browser/device_orientation/provider.h b/chrome/browser/device_orientation/provider.h new file mode 100644 index 0000000..aaa5106 --- /dev/null +++ b/chrome/browser/device_orientation/provider.h @@ -0,0 +1,55 @@ +// Copyright (c) 2010 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 CHROME_BROWSER_DEVICE_ORIENTATION_PROVIDER_H_ +#define CHROME_BROWSER_DEVICE_ORIENTATION_PROVIDER_H_ + +#include "base/logging.h" +#include "base/ref_counted.h" + +namespace device_orientation { + +class Orientation; + +class Provider : public base::RefCounted<Provider> { + public: + class Observer { + public: + // Called when the orientation changes. + // An Observer must not synchronously call Provider::RemoveObserver + // or Provider::AddObserver when this is called. + virtual void OnOrientationUpdate(const Orientation& orientation) = 0; + }; + + // Returns a pointer to the singleton instance of this class. + // The caller should store the returned pointer in a scoped_refptr. + // The Provider instance is lazily constructed when GetInstance() is called, + // and destructed when the last scoped_refptr referring to it is destructed. + static Provider* GetInstance(); + + // Inject a mock Provider for testing. Only a weak pointer to the injected + // object will be held by Provider, i.e. it does not itself contribute to the + // injected object's reference count. + static void SetInstanceForTests(Provider* provider); + + virtual void AddObserver(Observer* observer) {} + virtual void RemoveObserver(Observer* observer) {} + + protected: + Provider() {} + virtual ~Provider() { + DCHECK(instance_ == this); + instance_ = NULL; + } + + private: + friend class base::RefCounted<Provider>; + static Provider* instance_; + + DISALLOW_COPY_AND_ASSIGN(Provider); +}; + +} // namespace device_orientation + +#endif // CHROME_BROWSER_DEVICE_ORIENTATION_PROVIDER_H_ diff --git a/chrome/browser/renderer_host/resource_message_filter.cc b/chrome/browser/renderer_host/resource_message_filter.cc index 0c5fc51..db1ebd2 100644 --- a/chrome/browser/renderer_host/resource_message_filter.cc +++ b/chrome/browser/renderer_host/resource_message_filter.cc @@ -26,6 +26,7 @@ #include "chrome/browser/chrome_plugin_browsing_context.h" #include "chrome/browser/chrome_thread.h" #include "chrome/browser/clipboard_dispatcher.h" +#include "chrome/browser/device_orientation/dispatcher_host.h" #include "chrome/browser/download/download_file.h" #include "chrome/browser/extensions/extension_message_service.h" #include "chrome/browser/geolocation/geolocation_permission_context.h" @@ -235,9 +236,10 @@ ResourceMessageFilter::ResourceMessageFilter( new speech_input::SpeechInputDispatcherHost(this->id()))), ALLOW_THIS_IN_INITIALIZER_LIST(geolocation_dispatcher_host_( GeolocationDispatcherHost::New( - this->id(), profile->GetGeolocationPermissionContext()))) { + this->id(), profile->GetGeolocationPermissionContext()))), + ALLOW_THIS_IN_INITIALIZER_LIST(device_orientation_dispatcher_host_( + new device_orientation::DispatcherHost(this->id()))) { request_context_ = profile_->GetRequestContext(); - DCHECK(request_context_); DCHECK(media_request_context_); DCHECK(audio_renderer_host_.get()); @@ -336,7 +338,8 @@ bool ResourceMessageFilter::OnMessageReceived(const IPC::Message& msg) { mp_dispatcher->OnMessageReceived( msg, this, next_route_id_callback(), &msg_is_ok) || geolocation_dispatcher_host_->OnMessageReceived(msg, &msg_is_ok) || - speech_input_dispatcher_host_->OnMessageReceived(msg, &msg_is_ok); + speech_input_dispatcher_host_->OnMessageReceived(msg, &msg_is_ok) || + device_orientation_dispatcher_host_->OnMessageReceived(msg, &msg_is_ok); if (!handled) { DCHECK(msg_is_ok); // It should have been marked handled if it wasn't OK. @@ -1674,4 +1677,3 @@ void GetCookiesCompletion::RunWithParams(const Tuple1<int>& params) { delete this; } } - diff --git a/chrome/browser/renderer_host/resource_message_filter.h b/chrome/browser/renderer_host/resource_message_filter.h index 317f55e..19320e0 100644 --- a/chrome/browser/renderer_host/resource_message_filter.h +++ b/chrome/browser/renderer_host/resource_message_filter.h @@ -53,6 +53,10 @@ namespace base { class SharedMemory; } +namespace device_orientation { +class DispatcherHost; +} + namespace file_util { struct FileInfo; } @@ -452,6 +456,10 @@ class ResourceMessageFilter : public IPC::ChannelProxy::MessageFilter, // Used to handle geolocation-related messages. scoped_refptr<GeolocationDispatcherHost> geolocation_dispatcher_host_; + // Used to handle device orientation related messages. + scoped_refptr<device_orientation::DispatcherHost> + device_orientation_dispatcher_host_; + DISALLOW_COPY_AND_ASSIGN(ResourceMessageFilter); }; diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi index 7e9d7fe..2347018 100644 --- a/chrome/chrome_browser.gypi +++ b/chrome/chrome_browser.gypi @@ -1104,6 +1104,11 @@ 'browser/default_encoding_combo_model.h', 'browser/defaults.cc', 'browser/defaults.h', + 'browser/device_orientation/dispatcher_host.cc', + 'browser/device_orientation/dispatcher_host.h', + 'browser/device_orientation/orientation.h', + 'browser/device_orientation/provider.cc', + 'browser/device_orientation/provider.h', 'browser/diagnostics/diagnostics_main.cc', 'browser/diagnostics/diagnostics_main.h', 'browser/diagnostics/diagnostics_model.h', diff --git a/chrome/chrome_renderer.gypi b/chrome/chrome_renderer.gypi index dc5beef..47be2e6 100644 --- a/chrome/chrome_renderer.gypi +++ b/chrome/chrome_renderer.gypi @@ -87,6 +87,8 @@ 'renderer/blocked_plugin.h', 'renderer/cookie_message_filter.cc', 'renderer/cookie_message_filter.h', + 'renderer/device_orientation_dispatcher.cc', + 'renderer/device_orientation_dispatcher.h', 'renderer/devtools_agent.cc', 'renderer/devtools_agent.h', 'renderer/devtools_agent_filter.cc', diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi index efe1045..e31a25b 100644 --- a/chrome/chrome_tests.gypi +++ b/chrome/chrome_tests.gypi @@ -1546,6 +1546,7 @@ 'browser/cocoa/view_id_util_browsertest.mm', 'browser/cocoa/applescript/window_applescript_test.mm', 'browser/crash_recovery_browsertest.cc', + 'browser/device_orientation/device_orientation_browsertest.cc', 'browser/device_orientation/enable_switch_browsertest.cc', 'browser/dom_ui/file_browse_browsertest.cc', 'browser/dom_ui/mediaplayer_browsertest.cc', diff --git a/chrome/common/render_messages.h b/chrome/common/render_messages.h index 55e4044..e45d79d 100644 --- a/chrome/common/render_messages.h +++ b/chrome/common/render_messages.h @@ -829,6 +829,16 @@ struct ViewMsg_ExtensionExtentsUpdated_Params { std::vector<ViewMsg_ExtensionExtentInfo> extension_apps; }; +struct ViewMsg_DeviceOrientationUpdated_Params { + // These fields have the same meaning as in device_orientation::Orientation. + bool can_provide_alpha; + double alpha; + bool can_provide_beta; + double beta; + bool can_provide_gamma; + double gamma; +}; + // Values that may be OR'd together to form the 'flags' parameter of the // ViewMsg_EnablePreferredSizeChangedMode message. enum ViewHostMsg_EnablePreferredSizeChangedMode_Flags { @@ -3363,6 +3373,44 @@ struct ParamTraits<webkit_glue::WebAccessibility> { } }; +// Traits for ViewMsg_DeviceOrientationUpdated_Params +// structure to pack/unpack. +template <> +struct ParamTraits<ViewMsg_DeviceOrientationUpdated_Params> { + typedef ViewMsg_DeviceOrientationUpdated_Params param_type; + static void Write(Message* m, const param_type& p) { + WriteParam(m, p.can_provide_alpha); + WriteParam(m, p.alpha); + WriteParam(m, p.can_provide_beta); + WriteParam(m, p.beta); + WriteParam(m, p.can_provide_gamma); + WriteParam(m, p.gamma); + } + static bool Read(const Message* m, void** iter, param_type* p) { + return + ReadParam(m, iter, &p->can_provide_alpha) && + ReadParam(m, iter, &p->alpha) && + ReadParam(m, iter, &p->can_provide_beta) && + ReadParam(m, iter, &p->beta) && + ReadParam(m, iter, &p->can_provide_gamma) && + ReadParam(m, iter, &p->gamma); + } + static void Log(const param_type& p, std::wstring* l) { + l->append(L"("); + LogParam(p.can_provide_alpha, l); + l->append(L", "); + LogParam(p.alpha, l); + l->append(L", "); + LogParam(p.can_provide_beta, l); + l->append(L", "); + LogParam(p.beta, l); + l->append(L", "); + LogParam(p.can_provide_gamma, l); + l->append(L", "); + LogParam(p.gamma, l); + l->append(L")"); + } +}; } // namespace IPC #define MESSAGES_INTERNAL_FILE "chrome/common/render_messages_internal.h" diff --git a/chrome/common/render_messages_internal.h b/chrome/common/render_messages_internal.h index 674cb4f..7eb594d 100644 --- a/chrome/common/render_messages_internal.h +++ b/chrome/common/render_messages_internal.h @@ -993,6 +993,10 @@ IPC_BEGIN_MESSAGES(View) // ViewHostMsg_SpeechInput_StartRecognition. IPC_MESSAGE_ROUTED0(ViewMsg_SpeechInput_RecognitionComplete) + // Notification that the device's orientation has changed. + IPC_MESSAGE_ROUTED1(ViewMsg_DeviceOrientationUpdated, + ViewMsg_DeviceOrientationUpdated_Params) + IPC_END_MESSAGES(View) @@ -2609,4 +2613,15 @@ IPC_BEGIN_MESSAGES(ViewHost) IPC_MESSAGE_CONTROL1(ViewHostMsg_SpeechInput_StopRecording, int /* render_view_id */) + //--------------------------------------------------------------------------- + // Device orientation services messages: + + // A RenderView requests to start receiving device orientation updates. + IPC_MESSAGE_CONTROL1(ViewHostMsg_DeviceOrientation_StartUpdating, + int /* render_view_id */) + + // A RenderView requests to stop receiving device orientation updates. + IPC_MESSAGE_CONTROL1(ViewHostMsg_DeviceOrientation_StopUpdating, + int /* render_view_id */) + IPC_END_MESSAGES(ViewHost) diff --git a/chrome/renderer/device_orientation_dispatcher.cc b/chrome/renderer/device_orientation_dispatcher.cc new file mode 100644 index 0000000..1f7c72e --- /dev/null +++ b/chrome/renderer/device_orientation_dispatcher.cc @@ -0,0 +1,72 @@ +// Copyright (c) 2010 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 "chrome/renderer/device_orientation_dispatcher.h" + +#include "chrome/renderer/render_view.h" +#include "third_party/WebKit/WebKit/chromium/public/WebDeviceOrientation.h" +#include "third_party/WebKit/WebKit/chromium/public/WebDeviceOrientationController.h" + +DeviceOrientationDispatcher::DeviceOrientationDispatcher( + RenderView* render_view) + : render_view_(render_view), + controller_(NULL), + started_(false) { +} + +DeviceOrientationDispatcher::~DeviceOrientationDispatcher() { + if (started_) + stopUpdating(); +} + +bool DeviceOrientationDispatcher::OnMessageReceived(const IPC::Message& msg) { + bool handled = true; + IPC_BEGIN_MESSAGE_MAP(DeviceOrientationDispatcher, msg) + IPC_MESSAGE_HANDLER(ViewMsg_DeviceOrientationUpdated, + OnDeviceOrientationUpdated) + IPC_MESSAGE_UNHANDLED(handled = false) + IPC_END_MESSAGE_MAP() + return handled; +} + +void DeviceOrientationDispatcher::setController( + WebKit::WebDeviceOrientationController* controller) { + controller_.reset(controller); +} + +void DeviceOrientationDispatcher::startUpdating() { + render_view_->Send(new ViewHostMsg_DeviceOrientation_StartUpdating( + render_view_->routing_id())); + started_ = true; +} + +void DeviceOrientationDispatcher::stopUpdating() { + render_view_->Send(new ViewHostMsg_DeviceOrientation_StopUpdating( + render_view_->routing_id())); + started_ = false; +} + +WebKit::WebDeviceOrientation DeviceOrientationDispatcher::lastOrientation() + const { + if (!last_update_.get()) + return WebKit::WebDeviceOrientation::nullOrientation(); + + return WebKit::WebDeviceOrientation(last_update_->can_provide_alpha, + last_update_->alpha, + last_update_->can_provide_beta, + last_update_->beta, + last_update_->can_provide_gamma, + last_update_->gamma); +} + +void DeviceOrientationDispatcher::OnDeviceOrientationUpdated( + const ViewMsg_DeviceOrientationUpdated_Params& p) { + last_update_.reset(new ViewMsg_DeviceOrientationUpdated_Params(p)); + + WebKit::WebDeviceOrientation orientation(p.can_provide_alpha, p.alpha, + p.can_provide_beta, p.beta, + p.can_provide_gamma, p.gamma); + + controller_->didChangeDeviceOrientation(orientation); +} diff --git a/chrome/renderer/device_orientation_dispatcher.h b/chrome/renderer/device_orientation_dispatcher.h new file mode 100644 index 0000000..2e7c76f --- /dev/null +++ b/chrome/renderer/device_orientation_dispatcher.h @@ -0,0 +1,39 @@ +// Copyright (c) 2010 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 CHROME_RENDERER_DEVICE_ORIENTATION_DISPATCHER_H_ +#define CHROME_RENDERER_DEVICE_ORIENTATION_DISPATCHER_H_ + +#include "third_party/WebKit/WebKit/chromium/public/WebDeviceOrientationClient.h" + +#include "chrome/common/render_messages.h" + +class RenderView; +namespace IPC { class Message; } + +class DeviceOrientationDispatcher : public WebKit::WebDeviceOrientationClient { + public: + explicit DeviceOrientationDispatcher(RenderView* render_view); + virtual ~DeviceOrientationDispatcher(); + + bool OnMessageReceived(const IPC::Message& msg); + + // From WebKit::WebDeviceOrientationClient. + virtual void setController( + WebKit::WebDeviceOrientationController* controller); + virtual void startUpdating(); + virtual void stopUpdating(); + virtual WebKit::WebDeviceOrientation lastOrientation() const; + + private: + void OnDeviceOrientationUpdated( + const ViewMsg_DeviceOrientationUpdated_Params& p); + + RenderView* render_view_; + scoped_ptr<WebKit::WebDeviceOrientationController> controller_; + scoped_ptr<ViewMsg_DeviceOrientationUpdated_Params> last_update_; + bool started_; +}; + +#endif // CHROME_RENDERER_DEVICE_ORIENTATION_DISPATCHER_H_ diff --git a/chrome/renderer/render_view.cc b/chrome/renderer/render_view.cc index 517cc3b..fbc73ed 100644 --- a/chrome/renderer/render_view.cc +++ b/chrome/renderer/render_view.cc @@ -43,6 +43,7 @@ #include "chrome/renderer/about_handler.h" #include "chrome/renderer/audio_message_filter.h" #include "chrome/renderer/blocked_plugin.h" +#include "chrome/renderer/device_orientation_dispatcher.h" #include "chrome/renderer/devtools_agent.h" #include "chrome/renderer/devtools_client.h" #include "chrome/renderer/extension_groups.h" @@ -654,6 +655,10 @@ void RenderView::OnMessageReceived(const IPC::Message& message) { speech_input_dispatcher_->OnMessageReceived(message)) { return; } + if (device_orientation_dispatcher_.get() && + device_orientation_dispatcher_->OnMessageReceived(message)) { + return; + } IPC_BEGIN_MESSAGE_MAP(RenderView, message) IPC_MESSAGE_HANDLER(ViewMsg_CaptureThumbnail, OnCaptureThumbnail) @@ -5400,6 +5405,12 @@ WebKit::WebSpeechInputController* RenderView::speechInputController( return speech_input_dispatcher_.get(); } +WebKit::WebDeviceOrientationClient* RenderView::deviceOrientationClient() { + if (!device_orientation_dispatcher_.get()) + device_orientation_dispatcher_.reset(new DeviceOrientationDispatcher(this)); + return device_orientation_dispatcher_.get(); +} + bool RenderView::IsNonLocalTopLevelNavigation( const GURL& url, WebKit::WebFrame* frame, WebKit::WebNavigationType type) { // Must be a top level frame. diff --git a/chrome/renderer/render_view.h b/chrome/renderer/render_view.h index f31d27e..f4c6b46c 100644 --- a/chrome/renderer/render_view.h +++ b/chrome/renderer/render_view.h @@ -55,6 +55,7 @@ class AudioMessageFilter; class DictionaryValue; +class DeviceOrientationDispatcher; class DevToolsAgent; class DevToolsClient; class FilePath; @@ -417,6 +418,7 @@ class RenderView : public RenderWidget, virtual WebKit::WebGeolocationService* geolocationService(); virtual WebKit::WebSpeechInputController* speechInputController( WebKit::WebSpeechInputListener* listener); + virtual WebKit::WebDeviceOrientationClient* deviceOrientationClient(); // WebKit::WebFrameClient implementation ------------------------------------- @@ -1226,6 +1228,9 @@ class RenderView : public RenderWidget, // The speech dispatcher attached to this view, lazily initialized. scoped_ptr<SpeechInputDispatcher> speech_input_dispatcher_; + // Device orientation dispatcher attached to this view; lazily initialized. + scoped_ptr<DeviceOrientationDispatcher> device_orientation_dispatcher_; + // Misc ---------------------------------------------------------------------- // The current and pending file chooser completion objects. If the queue is diff --git a/chrome/test/data/device_orientation/device_orientation_test.html b/chrome/test/data/device_orientation/device_orientation_test.html new file mode 100644 index 0000000..95c68f5 --- /dev/null +++ b/chrome/test/data/device_orientation/device_orientation_test.html @@ -0,0 +1,36 @@ +<html> + <head> + <title>DeviceOrientation test</title> + <script type="text/javascript"> + var eventCount = 0; + + function checkOrientationEvent(event) { + // Return true iff the orientation is close enough to (1, 2, 3). + return Math.abs(event.alpha - 1) < 0.01 && + Math.abs(event.beta - 2) < 0.01 && + Math.abs(event.gamma - 3) < 0.01; + } + + function onOrientation(event) { + if (checkOrientationEvent(event)) { + window.removeEventListener('deviceorientation', onOrientation); + pass(); + } else { + fail(); + } + } + + function pass() { + document.getElementById('status').innerHTML = 'PASS'; + document.location = '#pass'; + } + + function fail() { + document.location = '#fail'; + } + </script> + </head> + <body onLoad="window.addEventListener('deviceorientation', onOrientation)"> + <div id="status">FAIL</div> + </body> +</html> |